From a48b1a725d3f90dbfea163f72a034e274aecdc5b Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 10 Apr 2009 20:59:44 +0000 Subject: [PATCH] change gpu to use only one function for 1D and 2D sprite rendering. this makes it easier to debug and tweak, since they were 95% similar already. also fix a bunch of bugs in the win32 oam viewer. --- desmume/src/GPU.cpp | 491 ++++++++----------------------- desmume/src/GPU.h | 12 +- desmume/src/MMU.cpp | 5 +- desmume/src/windows/oamView.cpp | 7 +- desmume/src/windows/resources.rc | 6 +- 5 files changed, 143 insertions(+), 378 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index d71ee38d3..bea3f6d1c 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -53,23 +53,6 @@ #include "debug.h" #include "NDSSystem.h" -//#define CHECKSPRITES - -#ifdef CHECKSPRITES -#define CHECK_SPRITE(type) \ -if (!src) {\ - INFO("Sprite%s(%s) in mode %i %s\n",\ - type==1?"1D":"2D",\ - dispCnt->OBJ_BMP_mapping==1?"1D":"2D",\ - spriteInfo->Mode,\ - (spriteInfo->RotScale & 1)?"(Rotoscaled)":"");\ -continue;\ -}; -#else -#define CHECK_SPRITE(type) if (!src) { continue; }; -#endif - - ARM9_struct ARM9Mem; extern BOOL click; @@ -293,7 +276,7 @@ void GPU_Reset(GPU *g, u8 l) g->BGSize[0][1] = g->BGSize[1][1] = g->BGSize[2][1] = g->BGSize[3][1] = 256; g->dispOBJ = g->dispBG[0] = g->dispBG[1] = g->dispBG[2] = g->dispBG[3] = TRUE; - g->spriteRender = sprite1D; + g->spriteRenderMode = GPU::SPRITE_1D; g->bgPrio[4] = 0xFF; @@ -469,20 +452,21 @@ void GPU_setVideoProp(GPU * gpu, u32 p) if(cnt->OBJ_Tile_mapping) { - /* 1-d sprite mapping */ + // 1-d sprite mapping // boundary : // core A : 32k, 64k, 128k, 256k // core B : 32k, 64k, 128k, 128k gpu->sprBoundary = 5 + cnt->OBJ_Tile_1D_Bound ; - if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) - gpu->sprBoundary = 7; + + //zero 10-apr-09 - this is just wrong. + //if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) gpu->sprBoundary = 7; - gpu->spriteRender = sprite1D; + gpu->spriteRenderMode = GPU::SPRITE_1D; } else { - /* 2d sprite mapping */ + // 2d sprite mapping // boundary : 32k gpu->sprBoundary = 5; - gpu->spriteRender = sprite2D; + gpu->spriteRenderMode = GPU::SPRITE_2D; } if(cnt->OBJ_BMP_1D_Bound && (gpu->core == GPU_MAIN)) @@ -2054,14 +2038,26 @@ FORCEINLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l, /*****************************************************************************/ // SPRITE RENDERING /*****************************************************************************/ -void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab) + +void GPU::spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab) { + if(spriteRenderMode == SPRITE_1D) + _spriteRender(dst,dst_alpha,typeTab, prioTab); + else + _spriteRender(dst,dst_alpha,typeTab, prioTab); +} + +template +void GPU::_spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab) +{ + u16 l = currLine; + GPU *gpu = this; + struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits; _OAM_ * spriteInfo = (_OAM_ *)(gpu->oam + (nbShow-1));// + 127; u8 block = gpu->sprBoundary; u16 i; - //for(i = 0; i> 1) | *(((u16*)spriteInfo)+1) << 15; *(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14; @@ -2074,8 +2070,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri ,*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15 ,*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14 #endif - ) /* check all sprites */ + ) { + const int oamNum = 127 - i; + //for each sprite: + size sprSize; s32 sprX, sprY, x, y, lg; int xdir; @@ -2158,8 +2157,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri // If we are using 1 palette of 256 colours if(spriteInfo->Depth) { + //2d: src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block)); - CHECK_SPRITE(1); + if (!src) { + continue; + } // If extended palettes are set, use them if (dispCnt->ExOBJPalette_Enable) @@ -2175,18 +2177,19 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) { - offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)*sprSize.x*8) + ((auxY&0x7)*8); + if(MODE == SPRITE_2D) + offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*8); + else + offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)*sprSize.x*8) + ((auxY&0x7)*8); + colour = src[offset]; if (colour && (prioTab[sprX]>=prio)) { - //if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, T1ReadWord(pal, colour<<1), sprX )) - { - T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); - dst_alpha[sprX] = 16; - typeTab[sprX] = spriteInfo->Mode; - prioTab[sprX] = prio; - } + T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); + dst_alpha[sprX] = 16; + typeTab[sprX] = spriteInfo->Mode; + prioTab[sprX] = prio; } } @@ -2205,7 +2208,10 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32); else src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16); - CHECK_SPRITE(1); + + if (!src) { + continue; + } for(j = 0; j < lg; ++j, ++sprX) { @@ -2215,18 +2221,19 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) { - offset = (auxX) + (auxY<<5); + if(MODE == SPRITE_2D) + offset = auxX + (auxY<<8); + else + offset = (auxX) + (auxY<<5); + colour = T1ReadWord (src, offset<<1); if((colour&0x8000) && (prioTab[sprX]>=prio)) { - // if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, colour, sprX)) - { - T2WriteWord(dst, (sprX<<1), colour); - dst_alpha[sprX] = spriteInfo->PaletteIndex; - typeTab[sprX] = spriteInfo->Mode; - prioTab[sprX] = prio; - } + T2WriteWord(dst, (sprX<<1), colour); + dst_alpha[sprX] = spriteInfo->PaletteIndex; + typeTab[sprX] = spriteInfo->Mode; + prioTab[sprX] = prio; } } @@ -2241,9 +2248,20 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri // Rotozoomed 16/16 palette else { - pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32); - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<sprBoundary)); - CHECK_SPRITE(1); + if(MODE == SPRITE_2D) + { + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5)); + pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32)); + } + else + { + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<sprBoundary)); + pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32); + } + + if (!src) { + continue; + } for(j = 0; j < lg; ++j, ++sprX) { @@ -2253,7 +2271,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) { - offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)*sprSize.x)*4 + ((auxY&0x7)*4); + if(MODE == SPRITE_2D) + offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*4); + else + offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)*sprSize.x)*4 + ((auxY&0x7)*4); + colour = src[offset]; // Get 4bits value from the readed 8bits @@ -2262,13 +2284,10 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri if(colour && (prioTab[sprX]>=prio)) { - //if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, T1ReadWord(pal, colour<<1), sprX )) - { - T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); - dst_alpha[sprX] = 16; - typeTab[sprX] = spriteInfo->Mode; - prioTab[sprX] = prio; - } + T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); + dst_alpha[sprX] = 16; + typeTab[sprX] = spriteInfo->Mode; + prioTab[sprX] = prio; } } @@ -2285,16 +2304,29 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri { u16 * pal; + if (!compute_sprite_vars(spriteInfo, l, sprSize, sprX, sprY, x, y, lg, xdir)) continue; if (spriteInfo->Mode == 2) { - if (spriteInfo->Depth) - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8)); + if(MODE == SPRITE_2D) + { + if (spriteInfo->Depth) + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); + else + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); + } else - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*4) + ((y&0x7)*4)); - CHECK_SPRITE(1); + { + if (spriteInfo->Depth) + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8)); + else + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*4) + ((y&0x7)*4)); + } + if (!src) { + continue; + } render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); continue; @@ -2315,7 +2347,10 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri else // 128 * 512 src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1)); } - CHECK_SPRITE(1); + + if (!src) { + continue; + } render_sprite_BMP (gpu, i, l, dst, (u16*)src, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->PaletteIndex); continue; @@ -2323,328 +2358,44 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri if(spriteInfo->Depth) /* 256 colors */ { - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8)); - CHECK_SPRITE(1); - - if (dispCnt->ExOBJPalette_Enable) - pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200)); - else - pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400); - - //sprwin test hack - to enable, only draw win and not sprite - render_sprite_256 (gpu, i, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1); - //render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); - - continue; - } - /* 16 colors */ - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*4) + ((y&0x7)*4)); - CHECK_SPRITE(1); - pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400); - - pal += (spriteInfo->PaletteIndex<<4); - - //sprwin test hack - to enable, only draw win and not sprite - render_sprite_16 (gpu, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1); - //render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); - } - } - -#ifdef WORDS_BIGENDIAN - *(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) << 1) | *(((u16*)spriteInfo)+1) >> 15; - *(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) << 2) | *(((u16*)spriteInfo)+2) >> 14; -#endif -} - -void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab) -{ - struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits; - _OAM_ * spriteInfo = (_OAM_*)(gpu->oam + (nbShow-1));// + 127; - u16 i; - -#ifdef WORDS_BIGENDIAN - *(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15; - *(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14; -#endif - - for(i = 0; i> 15 - ,*(((u16*)(spriteInfo+1))+2) = (*(((u16*)(spriteInfo+1))+2) << 2) | *(((u16*)(spriteInfo+1))+2) >> 14 - ,*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15 - ,*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14 -#endif - ) /* check all sprites */ - { - size sprSize; - s32 sprX, sprY, x, y, lg; - int xdir; - u8 prio, * src; - //u16 * pal; - u16 j; - - // Check if sprite is disabled before everything - if (spriteInfo->RotScale == 2) - continue; - - prio = spriteInfo->Priority; - - if (spriteInfo->RotScale & 1) - { - s32 fieldX, fieldY, auxX, auxY, realX, realY, offset; - u8 blockparameter, *pal; - s16 dx, dmx, dy, dmy; - u16 colour; - - // Get sprite positions and size - sprX = (spriteInfo->X<<23)>>23; - sprY = spriteInfo->Y; - sprSize = sprSizeTab[spriteInfo->Size][spriteInfo->Shape]; - - lg = sprSize.x; - - if (sprY>=192) - sprY = (s32)((s8)(spriteInfo->Y)); - - // Copy sprite size, to check change it if needed - fieldX = sprSize.x; - fieldY = sprSize.y; - - // If we are using double size mode, double our control vars - if (spriteInfo->RotScale & 2) - { - fieldX <<= 1; - fieldY <<= 1; - lg <<= 1; - } - - // Check if sprite enabled - if ((l = sprY+fieldY) || - (sprX==256) || (sprX+fieldX<=0)) - continue; - - y = l - sprY; - - // Get which four parameter block is assigned to this sprite - blockparameter = (spriteInfo->RotScalIndex + (spriteInfo->HFlip<< 3) + (spriteInfo->VFlip << 4))*4; - - // Get rotation/scale parameters - dx = (s16)(gpu->oam + blockparameter+0)->attr3; - dmx = (s16)(gpu->oam + blockparameter+1)->attr3; - dy = (s16)(gpu->oam + blockparameter+2)->attr3; - dmy = (s16)(gpu->oam + blockparameter+3)->attr3; - - // Calculate fixed poitn 8.8 start offsets - realX = ((sprSize.x) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx + y * dmx; - realY = ((sprSize.y) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy + y * dmy; - - if(sprX<0) - { - // If sprite is not in the window - if(sprX + fieldX <= 0) - continue; - - // Otherwise, is partially visible - lg += sprX; - realX -= sprX*dx; - realY -= sprX*dy; - sprX = 0; - } - else - { - if(sprX+fieldX>256) - lg = 256 - sprX; - } - - // If we are using 1 palette of 256 colours - if(spriteInfo->Depth) - { - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5)); - CHECK_SPRITE(2); - - // If extended palettes are set, use them - if (dispCnt->ExOBJPalette_Enable) - pal = (ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200)); - else - pal = (ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400); - - for(j = 0; j < lg; ++j, ++sprX) - { - // Get the integer part of the fixed point 8.8, and check if it lies inside the sprite data - auxX = (realX>>8); - auxY = (realY>>8); - - if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) - { - offset = (auxX&0x7) + ((auxX&0xFFF8)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*8); - colour = src[offset]; - - if (colour && (prioTab[sprX]>=prio)) - { - // if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, T1ReadWord(pal, colour<<1), sprX )) - { - T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); - dst_alpha[sprX] = 16; - typeTab[sprX] = spriteInfo->Mode; - prioTab[sprX] = prio; - } - } - } - - // Add the rotation/scale coeficients, here the rotation/scaling - // is performed - realX += dx; - realY += dy; - } - - continue; - } - // Rotozoomed direct color - else if(spriteInfo->Mode == 3) - { - if (dispCnt->OBJ_BMP_mapping) - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32); - else - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16); - CHECK_SPRITE(2); - - for(j = 0; j < lg; ++j, ++sprX) - { - // Get the integer part of the fixed point 8.8, and check if it lies inside the sprite data - auxX = (realX>>8); - auxY = (realY>>8); - - if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) - { - offset = auxX + (auxY<<8); - colour = T1ReadWord(src, offset<<1); - - if((colour&0x8000) && (prioTab[sprX]>=prio)) - { - // if (gpu->setFinalColorSpr(gpu, sprX << 1, 4, dst, colour, sprX )) - { - T2WriteWord(dst, (sprX<<1), colour); - dst_alpha[sprX] = spriteInfo->PaletteIndex; - typeTab[sprX] = spriteInfo->Mode; - prioTab[sprX] = prio; - } - } - } - - // Add the rotation/scale coeficients, here the rotation/scaling - // is performed - realX += dx; - realY += dy; - } - - continue; - } - // Rotozoomed 16/16 palette - else - { - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5)); - CHECK_SPRITE(2); - pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32)); - - for(j = 0; j < lg; ++j, ++sprX) - { - // Get the integer part of the fixed point 8.8, and check if it lies inside the sprite data - auxX = (realX>>8); - auxY = (realY>>8); - - if (auxX >= 0 && auxY >= 0 && auxX < sprSize.x && auxY < sprSize.y) - { - offset = ((auxX>>1)&0x3) + (((auxX>>1)&0xFFFC)<<3) + ((auxY>>3)<<10) + ((auxY&0x7)*4); - colour = src[offset]; - - if (auxX&1) colour >>= 4; - else colour &= 0xF; - - if(colour && (prioTab[sprX]>=prio)) - { - // if (gpu->setFinalColorSpr(gpu, sprX << 1,4,dst, T1ReadWord (pal, colour<<1), sprX)) - { - T2WriteWord(dst, (sprX<<1), T2ReadWord(pal, (colour<<1))); - dst_alpha[sprX] = 16; - typeTab[sprX] = spriteInfo->Mode; - prioTab[sprX] = prio; - } - } - } - - // Add the rotation/scale coeficients, here the rotation/scaling - // is performed - realX += dx; - realY += dy; - } - - continue; - } - } - else - { - u16 *pal; - - if (!compute_sprite_vars(spriteInfo, l, sprSize, sprX, sprY, x, y, lg, xdir)) - continue; - - if (spriteInfo->Mode == 2) { - if (spriteInfo->Depth) + if(MODE == SPRITE_2D) src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); else - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); - CHECK_SPRITE(2); - - render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); - continue; - } - - if (spriteInfo->Mode == 3) /* sprite is in BMP format */ - { - if (dispCnt->OBJ_BMP_mapping) - { - // TODO: fix it for sprite1D - //src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1)); - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<4) + (y<sprBMPBoundary)); - } - else - { - if (dispCnt->OBJ_BMP_2D_dim) // 256*256 - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1)); - else // 128 * 512 - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1)); - } - CHECK_SPRITE(2); - - render_sprite_BMP (gpu, i, l, dst, (u16*)src, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->PaletteIndex); - - continue; - } + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8)); - if(spriteInfo->Depth) /* 256 colors */ - { - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); - CHECK_SPRITE(2); - + if (!src) { + continue; + } + if (dispCnt->ExOBJPalette_Enable) pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200)); else pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400); - render_sprite_256 (gpu, i, l, dst, src, pal, + render_sprite_256 (gpu, i, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1); continue; } + // 16 colors + if(MODE == SPRITE_2D) + { + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); + } + else + { + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*4) + ((y&0x7)*4)); + } + + if (!src) { + continue; + } - /* 16 colors */ - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); - CHECK_SPRITE(2); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400); - + pal += (spriteInfo->PaletteIndex<<4); - render_sprite_16 (gpu, l, dst, src, pal, - dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1); + + render_sprite_16 (gpu, l, dst, src, pal, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo->Mode == 1); } } @@ -2654,6 +2405,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * pri #endif } + /*****************************************************************************/ // SCREEN FUNCTIONS /*****************************************************************************/ @@ -2879,7 +2631,8 @@ static void GPU_ligne_layer(NDS_Screen * screen, u16 l) //but it has been changed to write u32 instead of u16 for a little speedup for(int i = 0; i< 128; ++i) T2WriteWord(spr, i << 2, c | (c<<16)); - gpu->spriteRender(gpu, l, spr, sprAlpha, sprType, sprPrio); + + gpu->spriteRender(spr, sprAlpha, sprType, sprPrio); mosaicSpriteLine(gpu, l, spr, sprAlpha, sprType, sprPrio); diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 2297f8e45..a5004435d 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -403,6 +403,9 @@ void register_gl_fun(fun_gl_Begin beg,fun_gl_End end); #define ADDRESS_STEP_16KB 0x04000 #define ADDRESS_STEP_32KB 0x08000 #define ADDRESS_STEP_64kB 0x10000 +#define ADDRESS_STEP_128KB 0x20000 +#define ADDRESS_STEP_256KB 0x40000 +#define ADDRESS_MASK_256KB (ADDRESS_STEP_256KB-1) #ifdef WORDS_BIGENDIAN struct _TILEENTRY @@ -717,12 +720,17 @@ struct GPU typedef void (*FinalOBJColFunct)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u8 type, u16 x); typedef void (*Final3DColFunct)(GPU *gpu, u32 passing, u8 *dst, u16 color, u8 alpha, u16 x); - typedef void (*SpriteRenderFunct) (GPU * gpu, u16 l, u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab); int setFinalColorBck_funcNum; FinalOBJColFunct setFinalColorSpr; Final3DColFunct setFinalColor3D; - SpriteRenderFunct spriteRender; + enum SpriteRenderMode { + SPRITE_1D, SPRITE_2D + } spriteRenderMode; + + template + void _spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab); + void spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab); void setFinalColorBG(u16 color, u8 x); FORCEINLINE void setFinalBGColorSpecialNone(u16 color, u8 x, bool blend1); diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index e308ca1b5..4434eb6af 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -482,7 +482,10 @@ u8 *MMU_RenderMapToLCD(u32 vram_addr) // holes if ((vram_addr > 0x6080000) && (vram_addr < 0x6200000)) return NULL; // Engine ABG max 512KB if ((vram_addr > 0x6220000) && (vram_addr < 0x6400000)) return NULL; // Engine BBG max 128KB - if ((vram_addr > 0x6420000) && (vram_addr < 0x6600000)) return NULL; // Engine AOBJ max 256KB + if ((vram_addr >= 0x6440000) && (vram_addr < 0x6600000)) { + assert(false); //please verify + vram_addr = (vram_addr & ADDRESS_MASK_256KB) + 0x6440000; // Engine AOBJ max 256KB + } vram_addr &= 0x0FFFFFF; u8 engine = (vram_addr >> 21); diff --git a/desmume/src/windows/oamView.cpp b/desmume/src/windows/oamView.cpp index d39a23f58..6f38b00f3 100644 --- a/desmume/src/windows/oamView.cpp +++ b/desmume/src/windows/oamView.cpp @@ -39,7 +39,6 @@ typedef struct } oamview_struct; oamview_struct *OAMView = NULL; -//extern NDSSystem nds; const char dimm[4][4][8] = { @@ -180,9 +179,11 @@ LRESULT OamView_OnPaint(HWND hwnd, oamview_struct *win, WPARAM wParam, LPARAM lP SetWindowText(GetDlgItem(hwnd, IDC_PROP1), ""); } + GPU copy = *win->gpu; for(i = 0; i < 192; ++i) { - win->gpu->spriteRender(win->gpu, i, (u8*)(bitmap + i*256), bitmap_alpha + i*256, type + i*256, prio + i*256); + copy.currLine = i; + copy.spriteRender((u8*)(bitmap + i*256), bitmap_alpha + i*256, type + i*256, prio + i*256); } SetDIBitsToDevice(hdc, 180, 4, 256, 192, 0, 0, 0, 192, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); @@ -319,7 +320,7 @@ BOOL CALLBACK ViewOAMProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case IDC_SCR_SELECT : switch(HIWORD(wParam)) { - case CBN_CLOSEUP : + case CBN_SELCHANGE : { u32 sel = SendMessage(GetDlgItem(hwnd, IDC_SCR_SELECT), CB_GETCURSEL, 0, 0); switch(sel) diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index fd7835d70..b01438cb0 100644 --- a/desmume/src/windows/resources.rc +++ b/desmume/src/windows/resources.rc @@ -2238,7 +2238,7 @@ STYLE DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU CAPTION "OAM Fremviser" FONT 8, "MS Sans Serif", 0, 0, 1 { - COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWN + COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWNLIST SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT @@ -2274,7 +2274,7 @@ STYLE DS_CENTER | DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME CAPTION "OAM Viewer" FONT 8, "MS Sans Serif", 0, 0, 1 { - COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWN + COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWNLIST SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT @@ -2310,7 +2310,7 @@ STYLE DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU CAPTION "OAM Viewer" FONT 8, "MS Sans Serif", 0, 0, 1 { - COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWN + COMBOBOX IDC_SCR_SELECT, 4, 4, 90, 14, WS_TABSTOP | WS_TABSTOP | CBS_DROPDOWNLIST SCROLLBAR IDC_SCROLLER, 48, 20, 20, 14, WS_VISIBLE LTEXT "Mode :", IDC_STATIC, 4, 36, 45, 8, SS_LEFT LTEXT "Tile :", IDC_STATIC, 4, 46, 45, 8, SS_LEFT