...
DO NOT REVERT WORKING CODE !!! * never seen a well-formed typedef harming anybody. http://yabause.free.fr/wikini/wakka.php?wiki=CodePractices * files do not need to be STABLE though * if it compiles and work for some cases, why revert ? * why revert to an existing version ? ppl can get the STABLE versions if we just tell them which ones they are...
This commit is contained in:
parent
febadd0da5
commit
3820a04bda
|
@ -148,11 +148,15 @@ void GPU_resortBGs(GPU *gpu)
|
|||
memset(gpu->sprWin[i],0, 256);
|
||||
|
||||
// we don't need to check for windows here...
|
||||
gpu->LayersEnable[0] = gpu->dispBG[0] && cnt->BG0_Enable && !(gpu->dispCnt.bits.BG0_3D && (gpu->core==0)) ;
|
||||
gpu->LayersEnable[1] = gpu->dispBG[1] && cnt->BG1_Enable;
|
||||
gpu->LayersEnable[2] = gpu->dispBG[2] && cnt->BG2_Enable;
|
||||
gpu->LayersEnable[3] = gpu->dispBG[3] && cnt->BG3_Enable;
|
||||
gpu->LayersEnable[4] = gpu->dispOBJ && cnt->OBJ_Enable;
|
||||
// if we tick boxes, invisible layers become invisible & vice versa
|
||||
#define OP ^ !
|
||||
// if we untick boxes, layers become invisible
|
||||
//#define OP &&
|
||||
gpu->LayersEnable[0] = gpu->dispBG[0] OP(cnt->BG0_Enable && !(gpu->dispCnt.bits.BG0_3D && (gpu->core==0)));
|
||||
gpu->LayersEnable[1] = gpu->dispBG[1] OP(cnt->BG1_Enable);
|
||||
gpu->LayersEnable[2] = gpu->dispBG[2] OP(cnt->BG2_Enable);
|
||||
gpu->LayersEnable[3] = gpu->dispBG[3] OP(cnt->BG3_Enable);
|
||||
gpu->LayersEnable[4] = gpu->dispOBJ OP(cnt->OBJ_Enable);
|
||||
|
||||
// KISS ! lower priority first, if same then lower num
|
||||
for (i=0;i<NB_PRIORITIES;i++) {
|
||||
|
@ -220,26 +224,29 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
|
|||
if(cnt->OBJ_Tile_1D)
|
||||
{
|
||||
/* 1-d sprite mapping */
|
||||
/* TODO: better comment (and understanding btw 8S) */
|
||||
gpu->sprBlock = 5 + cnt->OBJ_Tile_1D_Bound ;
|
||||
// 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->sprBlock = 7;
|
||||
gpu->sprBoundary = 7;
|
||||
}
|
||||
gpu->spriteRender = sprite1D;
|
||||
} else {
|
||||
/* 2d sprite mapping */
|
||||
gpu->sprBlock = 5;
|
||||
// boundary : 32k
|
||||
gpu->sprBoundary = 5;
|
||||
gpu->spriteRender = sprite2D;
|
||||
}
|
||||
|
||||
if(cnt->OBJ_BMP_1D_Bound && (gpu->core == GPU_MAIN))
|
||||
{
|
||||
gpu->sprBMPBlock = 8;
|
||||
gpu->sprBMPBoundary = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpu->sprBMPBlock = 7;
|
||||
gpu->sprBMPBoundary = 7;
|
||||
}
|
||||
|
||||
gpu->sprEnable = cnt->OBJ_Enable;
|
||||
|
@ -295,19 +302,18 @@ void GPU_setBGProp(GPU * gpu, u16 num, u16 p)
|
|||
|
||||
void GPU_remove(GPU * gpu, u8 num)
|
||||
{
|
||||
gpu->dispBG[num] = 0;
|
||||
if (num == 4) gpu->dispOBJ = 0;
|
||||
else gpu->dispBG[num] = 0;
|
||||
GPU_resortBGs(gpu);
|
||||
}
|
||||
|
||||
void GPU_addBack(GPU * gpu, u8 num)
|
||||
{
|
||||
gpu->dispBG[num] = 1;
|
||||
if (num == 4) gpu->dispOBJ = 1;
|
||||
else gpu->dispBG[num] = 1;
|
||||
GPU_resortBGs(gpu);
|
||||
}
|
||||
|
||||
void GPU_toggleOBJ(GPU * gpu, u8 disp) {
|
||||
gpu->dispOBJ = disp;
|
||||
}
|
||||
|
||||
void GPU_scrollX(GPU * gpu, u8 num, u16 v)
|
||||
{
|
||||
|
@ -610,7 +616,6 @@ INLINE void renderline_setFinalColor(GPU *gpu,u32 passing,u8 bgnum,u8 *dst,u16 c
|
|||
//}
|
||||
}
|
||||
color = (sourceR & 0x1F) | ((sourceG & 0x1F) << 5) | ((sourceB & 0x1F) << 10) | 0x8000 ;
|
||||
#undef min
|
||||
}
|
||||
T2WriteWord(dst, passing, color) ;
|
||||
break ;
|
||||
|
@ -653,19 +658,24 @@ INLINE void renderline_setFinalColor(GPU *gpu,u32 passing,u8 bgnum,u8 *dst,u16 c
|
|||
} ;
|
||||
|
||||
/* render a text background to the combined pixelbuffer */
|
||||
INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 YBG, u16 LG)
|
||||
INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG, u16 YBG, u16 LG)
|
||||
{
|
||||
struct _BGxCNT bgCnt = gpu->bgCnt[num].bits;
|
||||
u16 lg = gpu->BGSize[num][0];
|
||||
u16 ht = gpu->BGSize[num][1];
|
||||
u16 tmp = ((YBG&(ht-1))>>3);
|
||||
u8 * map = gpu->BG_map_ram[num] + (tmp&31) * 64;
|
||||
u8 *dst = DST;
|
||||
u8 *tile;
|
||||
u8 *map = gpu->BG_map_ram[num] + (tmp&31) * 64;
|
||||
u8 *tile, *pal, *line;
|
||||
|
||||
u16 xoff = XBG;
|
||||
u8 * pal;
|
||||
u16 yoff;
|
||||
u16 x;
|
||||
u16 x = 0;
|
||||
u16 xfin;
|
||||
|
||||
s8 line_dir = 1;
|
||||
u8 pt_xor = 0;
|
||||
u8 * mapinfo;
|
||||
TILEENTRY tileentry;
|
||||
|
||||
if(tmp>31)
|
||||
{
|
||||
|
@ -675,8 +685,11 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
tile = (u8*) gpu->BG_tile_ram[num];
|
||||
if((!tile) || (!gpu->BG_map_ram[num])) return; /* no tiles or no map*/
|
||||
xoff = XBG;
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
|
||||
if(!bgCnt.Palette_256) /* color: 16 palette entries */
|
||||
{
|
||||
|
||||
if (bgCnt.Mosaic_Enable){
|
||||
/* test NDS: #2 of
|
||||
http://desmume.sourceforge.net/forums/index.php?action=vthread&forum=2&topic=50&page=0#msg192 */
|
||||
|
@ -684,355 +697,284 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
u8 mw = (gpu->MOSAIC & 0xF) +1 ; /* horizontal granularity of the mosaic */
|
||||
u8 mh = ((gpu->MOSAIC>>4) & 0xF) +1 ; /* vertical granularity of the mosaic */
|
||||
YBG = (YBG / mh) * mh ; /* align y by vertical granularity */
|
||||
|
||||
yoff = ((YBG&7)<<2);
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
for(x = 0; x < LG;)
|
||||
|
||||
xfin = 8 - (xoff&7);
|
||||
for(x = 0; x < LG; xfin = min(x+8, LG))
|
||||
{
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 *line;
|
||||
u16 xfin;
|
||||
u8 pt = 0, save = 0;
|
||||
tmp = ((xoff&(lg-1))>>3);
|
||||
mapinfo = map + (tmp&0x1F) * 2;
|
||||
if(tmp>31) mapinfo += 32*32*2;
|
||||
mapinfovalue = T1ReadWord(mapinfo, 0);
|
||||
tileentry.val = T1ReadWord(mapinfo, 0);
|
||||
|
||||
line = (u8*)tile + (tileentry.bits.TileNum * 0x20) + ((tileentry.bits.VFlip)? (7*4)-yoff:yoff);
|
||||
|
||||
line = (u8 * )tile + ((mapinfovalue&0x3FF) * 0x20) + (((mapinfovalue)& 0x800 ? (7*4)-yoff : yoff));
|
||||
xfin = x + (8 - (xoff&7));
|
||||
if (xfin > LG)
|
||||
xfin = LG;
|
||||
|
||||
#define RENDERL(c,m) \
|
||||
if (c) renderline_setFinalColor(gpu,0,num,dst,T1ReadWord(pal, ((c) + ((mapinfovalue>>12)&0xF) * m) << 1),x,Y) ; \
|
||||
if (c) renderline_setFinalColor(gpu,0,num,dst,T1ReadWord(pal, ((c) + (tileentry.bits.Palette* m)) << 1),x,Y) ; \
|
||||
dst += 2; x++; xoff++;
|
||||
|
||||
|
||||
if((mapinfovalue) & 0x400)
|
||||
if(tileentry.bits.HFlip)
|
||||
{
|
||||
u8 pt = 0 ;
|
||||
u8 save = 0;
|
||||
|
||||
line += 3 - ((xoff&7)>>1);
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
if ((pt % mw) == 0) { /* only update the color we draw every mw pixels */
|
||||
if (pt & 1) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
save = (*line) >> 4 ;
|
||||
}
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
pt++ ;
|
||||
if (!(pt % mw)) { /* next pixel next possible color update */
|
||||
if (pt & 1) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
save = (*line) >> 4 ;
|
||||
}
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
line--; pt++ ;
|
||||
}
|
||||
line_dir = -1;
|
||||
pt_xor = 0;
|
||||
} else {
|
||||
u8 pt = 0 ;
|
||||
u8 save = 0;
|
||||
line += ((xoff&7)>>1);
|
||||
|
||||
for(; x < xfin; ) {
|
||||
line_dir = 1;
|
||||
pt_xor = 1;
|
||||
}
|
||||
// XXX
|
||||
if (!(pt % mw)) { /* only update the color we draw every n mw pixels */
|
||||
if (!(pt & 1)) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
save = (*line) >> 4 ;
|
||||
}
|
||||
for(; x < xfin; ) {
|
||||
if (!(pt % mw)) { /* only update the color we draw every n mw pixels */
|
||||
if ((pt & 1)^pt_xor) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
save = (*line) >> 4 ;
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
pt++ ;
|
||||
if (!(pt % mw)) { /* next pixel next possible color update */
|
||||
if (!(pt & 1)) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
save = (*line) >> 4 ;
|
||||
}
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
line++; pt++ ;
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
pt++ ;
|
||||
if (!(pt % mw)) { /* next pixel next possible color update */
|
||||
if ((pt & 1)^pt_xor) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
save = (*line) >> 4 ;
|
||||
}
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
line+=line_dir; pt++ ;
|
||||
}
|
||||
}
|
||||
} else { /* no mosaic mode */
|
||||
|
||||
yoff = ((YBG&7)<<2);
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
for(x = 0; x < LG;)
|
||||
xfin = 8 - (xoff&7);
|
||||
for(x = 0; x < LG; xfin = min(x+8, LG))
|
||||
{
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 *line;
|
||||
u16 xfin;
|
||||
tmp = ((xoff&(lg-1))>>3);
|
||||
mapinfo = map + (tmp&0x1F) * 2;
|
||||
if(tmp>31) mapinfo += 32*32*2;
|
||||
mapinfovalue = T1ReadWord(mapinfo, 0);
|
||||
tileentry.val = T1ReadWord(mapinfo, 0);
|
||||
|
||||
line = (u8 * )tile + ((mapinfovalue&0x3FF) * 0x20) + (((mapinfovalue)& 0x800 ? (7*4)-yoff : yoff));
|
||||
xfin = x + (8 - (xoff&7));
|
||||
if (xfin > LG)
|
||||
xfin = LG;
|
||||
|
||||
if((mapinfovalue) & 0x400)
|
||||
line = (u8 * )tile + (tileentry.bits.TileNum * 0x20) + ((tileentry.bits.VFlip) ? (7*4)-yoff : yoff);
|
||||
|
||||
if(tileentry.bits.HFlip)
|
||||
{
|
||||
line += 3 - ((xoff&7)>>1);
|
||||
//x=xfin; continue;
|
||||
line += (3 - ((xoff&7)>>1));
|
||||
line_dir = -1;
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
RENDERL(((*line)>>4),0x10)
|
||||
RENDERL(((*line)&0xF),0x10)
|
||||
line--;
|
||||
line += line_dir;
|
||||
}
|
||||
} else {
|
||||
line += ((xoff&7)>>1);
|
||||
line_dir = 1;
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
RENDERL(((*line)&0xF),0x10)
|
||||
RENDERL(((*line)>>4),0x10)
|
||||
line++;
|
||||
line += line_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!gpu->dispCnt.bits.ExBGxPalette_Enable) /* color: no extended palette */
|
||||
{
|
||||
yoff = ((YBG&7)<<3);
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
for(x = 0; x < LG;)
|
||||
xfin = 8 - (xoff&7);
|
||||
for(x = 0; x < LG; xfin = min(x+8, LG))
|
||||
{
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 *line;
|
||||
u16 xfin;
|
||||
tmp = ((xoff&(lg-1))>>3);
|
||||
tmp = (xoff & (lg-1))>>3;
|
||||
mapinfo = map + (tmp & 31) * 2;
|
||||
mapinfovalue;
|
||||
|
||||
if(tmp > 31) mapinfo += 32*32*2;
|
||||
tileentry.val = T1ReadWord(mapinfo, 0);
|
||||
|
||||
line = (u8 * )tile + (tileentry.bits.TileNum*0x40) + ((tileentry.bits.VFlip) ? (7*8)-yoff : yoff);
|
||||
|
||||
mapinfovalue = T1ReadWord(mapinfo, 0);
|
||||
|
||||
line = (u8 * )tile + ((mapinfovalue&0x3FF)*0x40) + (((mapinfovalue)& 0x800 ? (7*8)-yoff : yoff));
|
||||
xfin = x + (8 - (xoff&7));
|
||||
if (xfin > LG)
|
||||
xfin = LG;
|
||||
|
||||
if((mapinfovalue)& 0x400)
|
||||
if(tileentry.bits.HFlip)
|
||||
{
|
||||
line += (7 - (xoff&7));
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0)
|
||||
line--;
|
||||
}
|
||||
} else
|
||||
{
|
||||
line_dir = -1;
|
||||
} else {
|
||||
line += (xoff&7);
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0)
|
||||
line++;
|
||||
}
|
||||
line_dir = 1;
|
||||
}
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0)
|
||||
line += line_dir;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* color: extended palette */
|
||||
|
||||
/* color: extended palette */
|
||||
pal = ARM9Mem.ExtPal[gpu->core][gpu->BGExtPalSlot[num]];
|
||||
if(!pal) return;
|
||||
|
||||
yoff = ((YBG&7)<<3);
|
||||
|
||||
for(x = 0; x < LG;)
|
||||
xfin = 8 - (xoff&7);
|
||||
for(x = 0; x < LG; xfin = min(x+8, LG))
|
||||
{
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 * line;
|
||||
u16 xfin;
|
||||
tmp = ((xoff&(lg-1))>>3);
|
||||
mapinfo = map + (tmp & 0x1F) * 2;
|
||||
mapinfovalue;
|
||||
|
||||
if(tmp>31) mapinfo += 32 * 32 * 2;
|
||||
tileentry.val = T1ReadWord(mapinfo, 0);
|
||||
|
||||
mapinfovalue = T1ReadWord(mapinfo, 0);
|
||||
|
||||
line = (u8 * )tile + ((mapinfovalue&0x3FF)*0x40) + (((mapinfovalue)& 0x800 ? (7*8)-yoff : yoff));
|
||||
xfin = x + (8 - (xoff&7));
|
||||
if (xfin > LG)
|
||||
xfin = LG;
|
||||
line = (u8 * )tile + (tileentry.bits.TileNum*0x40) + ((tileentry.bits.VFlip)? (7*8)-yoff : yoff);
|
||||
|
||||
if((mapinfovalue)& 0x400)
|
||||
if(tileentry.bits.HFlip)
|
||||
{
|
||||
line += (7 - (xoff&7));
|
||||
for(; x < xfin;)
|
||||
{
|
||||
/* this is was adapted */
|
||||
RENDERL((*line),0x100)
|
||||
line--;
|
||||
}
|
||||
} else
|
||||
{
|
||||
line_dir = -1;
|
||||
} else {
|
||||
line += (xoff&7);
|
||||
for(; x < xfin; )
|
||||
{
|
||||
/* this is was adapted */
|
||||
RENDERL((*line),0x100)
|
||||
line++;
|
||||
}
|
||||
line_dir = 1;
|
||||
}
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0x100)
|
||||
line += line_dir;
|
||||
}
|
||||
}
|
||||
#undef RENDERL
|
||||
}
|
||||
|
||||
INLINE void rotBG2(GPU * gpu, u8 num, u8 * DST, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, u16 LG)
|
||||
{
|
||||
struct _BGxCNT bgCnt = gpu->bgCnt[num].bits;
|
||||
|
||||
s32 x = X + (s32)PB*(s32)H;
|
||||
s32 y = Y + (s32)PD*(s32)H;
|
||||
// scale rot
|
||||
|
||||
void rot_tiled_8bit_entry(GPU * gpu, int num, int auxX, int auxY, int lg, u8 * dst, u8 * map, u8 * tile, u8 * pal) {
|
||||
u8 palette_entry;
|
||||
u16 tileindex, x, y, color;
|
||||
|
||||
s32 dx = (s32)PA;
|
||||
s32 dy = (s32)PC;
|
||||
tileindex = map[(auxX + auxY * lg)>>3];
|
||||
x = (auxX&7); y = (auxY&7);
|
||||
|
||||
s32 auxX;
|
||||
s32 auxY;
|
||||
|
||||
s32 lg = gpu->BGSize[num][0];
|
||||
s32 ht = gpu->BGSize[num][1];
|
||||
s32 lgmap = (lg>>3);
|
||||
|
||||
u8 * map = gpu->BG_map_ram[num];
|
||||
u8 * tile = (u8 *)gpu->BG_tile_ram[num];
|
||||
u8 * dst = DST;
|
||||
u8 mapinfo;
|
||||
u8 coul;
|
||||
u8 * pal;
|
||||
u32 i;
|
||||
|
||||
if((!tile)||(!map)) return;
|
||||
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400;
|
||||
for(i = 0; i < LG; ++i)
|
||||
{
|
||||
auxX = x>>8;
|
||||
auxY = y>>8;
|
||||
|
||||
if(bgCnt.PaletteSet_Wrap)
|
||||
{
|
||||
auxX &= (lg-1);
|
||||
auxY &= (ht-1);
|
||||
}
|
||||
|
||||
if ((auxX >= 0) && (auxX < lg) && (auxY >= 0) && (auxY < ht))
|
||||
{
|
||||
mapinfo = map[(auxX>>3) + ((auxY>>3) * lgmap)];
|
||||
coul = tile[mapinfo*64 + ((auxY&7)<<3) + (auxX&7)];
|
||||
if(coul)
|
||||
renderline_setFinalColor(gpu,0,num,dst,T1ReadWord(pal, coul << 1),i,X);
|
||||
}
|
||||
dst += 2;
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
palette_entry = tile[(tileindex<<6)+(y<<3)+x];
|
||||
color = T1ReadWord(pal, palette_entry << 1);
|
||||
if (palette_entry)
|
||||
renderline_setFinalColor(gpu,0,num,dst, color,auxX,auxY);
|
||||
}
|
||||
|
||||
INLINE void extRotBG2(GPU * gpu, u8 num, u8 * DST, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, s16 LG)
|
||||
void rot_tiled_16bit_entry(GPU * gpu, int num, int auxX, int auxY, int lg, u8 * dst, u8 * map, u8 * tile, u8 * pal) {
|
||||
u8 palette_entry, palette_set;
|
||||
u16 tileindex, x, y, color;
|
||||
|
||||
if (!tile) return;
|
||||
tileindex = T1ReadWord(map, ((auxX + auxY * lg)>>3) << 1);
|
||||
palette_set = tileindex >> 12;
|
||||
tileindex &= 0x3FF;
|
||||
x = (palette_set & 1) ? 7 - (auxX&7) : (auxX&7);
|
||||
y = (palette_set & 2) ? 7 - (auxY&7) : (auxY&7);
|
||||
|
||||
palette_entry = tile[(tileindex<<6)+(y<<3)+x];
|
||||
color = T1ReadWord(pal, (palette_entry + (palette_set<<8)) << 1);
|
||||
if (palette_entry)
|
||||
renderline_setFinalColor(gpu,0,num,dst, color, auxX, auxY);
|
||||
}
|
||||
|
||||
void rot_256_map(GPU * gpu, int num, int auxX, int auxY, int lg, u8 * dst, u8 * map, u8 * tile, u8 * pal) {
|
||||
u8 palette_entry;
|
||||
u16 tileindex, color;
|
||||
|
||||
palette_entry = map[auxX + auxY * lg];
|
||||
color = T1ReadWord(pal, palette_entry << 1);
|
||||
if(palette_entry)
|
||||
renderline_setFinalColor(gpu,0,num,dst, color, auxX, auxY);
|
||||
|
||||
}
|
||||
|
||||
void rot_BMP_map(GPU * gpu, int num, int auxX, int auxY, int lg, u8 * dst, u8 * map, u8 * tile, u8 * pal) {
|
||||
u16 color;
|
||||
|
||||
color = T1ReadWord(map, (auxX + auxY * lg) << 1);
|
||||
if (color&0x8000)
|
||||
renderline_setFinalColor(gpu,0,num,dst, color, auxX, auxY);
|
||||
|
||||
}
|
||||
|
||||
typedef void (*rot_fun)(GPU * gpu, int num, int auxX, int auxY, int lg, u8 * dst, u8 * map, u8 * tile, u8 * pal);
|
||||
|
||||
INLINE void apply_rot_fun(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, u16 LG, rot_fun fun, u8 * map, u8 * tile, u8 * pal)
|
||||
{
|
||||
ROTOCOORD x, y;
|
||||
struct _BGxCNT bgCnt = gpu->bgCnt[num].bits;
|
||||
|
||||
s32 dx = (s32)PA;
|
||||
s32 dy = (s32)PC;
|
||||
s32 lg = gpu->BGSize[num][0];
|
||||
s32 ht = gpu->BGSize[num][1];
|
||||
u32 i, auxX, auxY;
|
||||
|
||||
if (!map) return;
|
||||
x.val = X + (s32)PB*(s32)H;
|
||||
y.val = Y + (s32)PD*(s32)H;
|
||||
|
||||
for(i = 0; i < LG; ++i)
|
||||
{
|
||||
auxX = x.bits.Integer;
|
||||
auxY = y.bits.Integer;
|
||||
|
||||
if(bgCnt.PaletteSet_Wrap)
|
||||
{
|
||||
// wrap
|
||||
auxX = auxX & (lg-1);
|
||||
auxY = auxY & (ht-1);
|
||||
}
|
||||
|
||||
if ((auxX >= 0) && (auxX < lg) && (auxY >= 0) && (auxY < ht))
|
||||
fun(gpu, num, auxX, auxY, lg, dst, map, tile, pal);
|
||||
dst += 2;
|
||||
x.val += dx;
|
||||
y.val += dy;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void rotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, u16 LG) {
|
||||
u8 * map = gpu->BG_map_ram[num];
|
||||
u8 * tile = (u8 *)gpu->BG_tile_ram[num];
|
||||
u8 * pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400;
|
||||
// printf("rot mode\n");
|
||||
apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_tiled_8bit_entry, map, tile, pal);
|
||||
}
|
||||
|
||||
INLINE void extRotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, s16 LG)
|
||||
{
|
||||
struct _BGxCNT bgCnt = gpu->bgCnt[num].bits;
|
||||
|
||||
s32 x = X + (s32)PB*(s32)H;
|
||||
s32 y = Y + (s32)PD*(s32)H;
|
||||
|
||||
s32 dx = PA;
|
||||
s32 dy = PC;
|
||||
|
||||
s32 auxX;
|
||||
s32 auxY;
|
||||
|
||||
s16 lg = gpu->BGSize[num][0];
|
||||
s16 ht = gpu->BGSize[num][1];
|
||||
u16 lgmap = (lg>>3);
|
||||
|
||||
u8 * tile = (u8 *)gpu->BG_tile_ram[num];
|
||||
u8 * dst = DST;
|
||||
u8 * map;
|
||||
u16 mapinfo, i;
|
||||
u8 coul;
|
||||
u8 *map, *tile, *pal;
|
||||
u8 affineModeSelection ;
|
||||
|
||||
/* see: http://nocash.emubase.de/gbatek.htm#dsvideobgmodescontrol */
|
||||
affineModeSelection = (bgCnt.Palette_256 << 1) | (bgCnt.CharacBase_Block & 1) ;
|
||||
// printf("extrot mode %d\n", affineModeSelection);
|
||||
switch(affineModeSelection)
|
||||
{
|
||||
case 0 :
|
||||
case 1 :
|
||||
{
|
||||
u8 * pal = ARM9Mem.ExtPal[gpu->core][gpu->BGExtPalSlot[num]];
|
||||
if(!pal) return;
|
||||
|
||||
#define LOOP(c) \
|
||||
for(i = 0; i < LG; ++i) { \
|
||||
auxX = x>>8; auxY = y>>8; \
|
||||
if(bgCnt.PaletteSet_Wrap) { \
|
||||
auxX &= (lg-1); auxY &= (ht-1); \
|
||||
} \
|
||||
if ((auxX >= 0) && (auxX < lg) && (auxY >= 0) && (auxY < ht)) c \
|
||||
dst += 2; x += dx; y += dy; \
|
||||
}
|
||||
case 0 :
|
||||
case 1 :
|
||||
// 16 bit bgmap entries
|
||||
map = gpu->BG_map_ram[num];
|
||||
LOOP(
|
||||
{
|
||||
u16 x1;
|
||||
u16 y1;
|
||||
mapinfo = T1ReadWord(map, ((auxX>>3) + (auxY>>3) * lgmap) << 1);
|
||||
|
||||
x1 = (mapinfo & 0x400) ? 7 - (auxX&7) : (auxX&7);
|
||||
y1 = (mapinfo & 0x800) ? 7 - (auxY&7) : (auxY&7);
|
||||
coul = tile[(mapinfo&0x3FF)*64 + x1 + (y1<<3)];
|
||||
if(coul)
|
||||
renderline_setFinalColor(gpu,0,num,dst, T1ReadWord(pal, (coul + (mapinfo>>12)*0x100) << 1),i,H);
|
||||
})
|
||||
|
||||
}
|
||||
tile = gpu->BG_tile_ram[num];
|
||||
pal = ARM9Mem.ExtPal[gpu->core][gpu->BGExtPalSlot[num]];
|
||||
apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_tiled_16bit_entry, map, tile, pal);
|
||||
return;
|
||||
case 2 :
|
||||
{
|
||||
u8 * pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400;
|
||||
u8 * map = gpu->BG_bmp_ram[num];
|
||||
LOOP(
|
||||
{
|
||||
mapinfo = map[auxX + auxY * lg];
|
||||
if(mapinfo)
|
||||
renderline_setFinalColor(gpu,0,num,dst, T1ReadWord(pal, mapinfo << 1),i,H);
|
||||
})
|
||||
}
|
||||
// 256 colors
|
||||
map = gpu->BG_bmp_ram[num];
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400;
|
||||
apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_256_map, map, NULL, pal);
|
||||
return;
|
||||
case 3 : /* direct color bitmap */
|
||||
{
|
||||
u8 * map = gpu->BG_bmp_ram[num];
|
||||
LOOP(
|
||||
{
|
||||
mapinfo = T1ReadWord(map, (auxX + auxY * lg) << 1);
|
||||
if ((mapinfo) && (mapinfo & 0x8000))
|
||||
renderline_setFinalColor(gpu,0,num,dst, mapinfo,i,H);
|
||||
})
|
||||
}
|
||||
case 3 :
|
||||
// direct colors / BMP
|
||||
map = gpu->BG_bmp_ram[num];
|
||||
apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_BMP_map, map, NULL, NULL);
|
||||
return;
|
||||
#undef LOOP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lineText(GPU * gpu, u8 num, u16 l, u8 * DST)
|
||||
|
@ -1112,7 +1054,6 @@ INLINE void render_sprite_BMP (GPU * gpu, u16 l, u8 * dst, u16 * src,
|
|||
for(i = 0; i < lg; i++, ++sprX, x+=xdir)
|
||||
{
|
||||
color = src[x];
|
||||
//RENDER_COND(color,)
|
||||
// alpha bit = invisible
|
||||
RENDER_COND(color&0x8000)
|
||||
}
|
||||
|
@ -1251,82 +1192,96 @@ INLINE void render_sprite_Win (GPU * gpu, u16 l, u8 * src,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return val means if the sprite is to be drawn or not
|
||||
INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
|
||||
size *sprSize, s32 *sprX, s32 *sprY, s32 *x, s32 *y, s32 *lg, int *xdir) {
|
||||
|
||||
*x = 0;
|
||||
// get sprite location 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));
|
||||
|
||||
// FIXME: for rot/scale, a list of entries into the sprite should be maintained,
|
||||
// that tells us where the first pixel of a screenline starts in the sprite,
|
||||
// and how a step to the right in a screenline translates within the sprite
|
||||
|
||||
if ((spriteInfo->RotScale == 2) || /* rotscale == 2 => sprite disabled */
|
||||
(l<*sprY)||(l>=*sprY+sprSize->y) || /* sprite lines outside of screen */
|
||||
(*sprX==256)||(*sprX+sprSize->x<0)) /* sprite pixels outside of line */
|
||||
return FALSE; /* not to be drawn */
|
||||
|
||||
// sprite portion out of the screen (LEFT)
|
||||
if(*sprX<0)
|
||||
{
|
||||
*lg += *sprX;
|
||||
*x = -(*sprX);
|
||||
*sprX = 0;
|
||||
// sprite portion out of the screen (RIGHT)
|
||||
} else if (*sprX+sprSize->x >= 256)
|
||||
*lg = 256 - *sprX;
|
||||
|
||||
*y = l - *sprY; /* get the y line within sprite coords */
|
||||
|
||||
// switch TOP<-->BOTTOM
|
||||
if (spriteInfo->VFlip)
|
||||
*y = sprSize->y - *y -1;
|
||||
|
||||
// switch LEFT<-->RIGHT
|
||||
if (spriteInfo->HFlip) {
|
||||
*x = sprSize->x - *x -1;
|
||||
*xdir = -1;
|
||||
} else {
|
||||
*xdir = 1;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
INLINE void compute_sprite_rotoscale(GPU * gpu, _OAM_ * spriteInfo,
|
||||
u16 * rotScaleA, u16 * rotScaleB, u16 * rotScaleC, u16 * rotScaleD) {
|
||||
u16 rotScaleIndex;
|
||||
// index from 0 to 31
|
||||
rotScaleIndex = spriteInfo->RotScalIndex + (spriteInfo->HFlip<<1) + (spriteInfo->VFlip << 2);
|
||||
/* if we need to do rotscale, gather its parameters */
|
||||
/* http://nocash.emubase.de/gbatek.htm#lcdobjoamrotationscalingparameters */
|
||||
*rotScaleA = T1ReadWord((u8*)(gpu->oam + rotScaleIndex*0x20 + 0x06),0) ;
|
||||
*rotScaleB = T1ReadWord((u8*)(gpu->oam + rotScaleIndex*0x20 + 0x0E),0) ;
|
||||
*rotScaleC = T1ReadWord((u8*)(gpu->oam + rotScaleIndex*0x20 + 0x16),0) ;
|
||||
*rotScaleD = T1ReadWord((u8*)(gpu->oam + rotScaleIndex*0x20 + 0x1E),0) ;
|
||||
}
|
||||
|
||||
void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
||||
{
|
||||
_OAM_ * spriteInfo = (_OAM_ *)(gpu->oam + (nbShow-1));// + 127;
|
||||
u8 block = gpu->sprBlock;
|
||||
u8 block = gpu->sprBoundary;
|
||||
u16 i;
|
||||
|
||||
for(i = 0; i<nbShow; ++i, --spriteInfo) /* check all sprites */
|
||||
{
|
||||
s32 sprX;
|
||||
s32 sprY;
|
||||
s32 x = 0;
|
||||
u32 lg;
|
||||
size sprSize;
|
||||
s32 y;
|
||||
u8 prio;
|
||||
u8 * src;
|
||||
u8 * pal;
|
||||
u16 i,j;
|
||||
s32 sprX, sprY, x, y, lg;
|
||||
int xdir;
|
||||
u8 prio, * src, * pal;
|
||||
u16 i,j;
|
||||
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD;
|
||||
|
||||
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD ;
|
||||
if (spriteInfo->RotScale & 1) {
|
||||
/* if we need to do rotscale, gather its parameters */
|
||||
/* http://nocash.emubase.de/gbatek.htm#lcdobjoamrotationscalingparameters */
|
||||
rotScaleA = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x06,0) ;
|
||||
rotScaleB = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x0E,0) ;
|
||||
rotScaleC = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x16,0) ;
|
||||
rotScaleD = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x1E,0) ;
|
||||
} ;
|
||||
|
||||
|
||||
// get sprite location 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));
|
||||
|
||||
/* FIXME: for rot/scale, a list of entries into the sprite should be maintained, that tells us where the first pixel */
|
||||
/* of a screenline starts in the sprite, and how a step to the right in a screenline translates within the sprite */
|
||||
if( (spriteInfo->RotScale == 2) || /* rotscale == 2 => sprite disabled */
|
||||
(l<sprY)||(l>=sprY+sprSize.y) || /* sprite occupies only lines outside the current drawn line */
|
||||
(sprX==256) ) /* sprite is outside our line */
|
||||
continue; /* for all these problems, continue with the next sprite */
|
||||
|
||||
// sprite portion out of the screen (LEFT)
|
||||
if(sprX<0)
|
||||
{
|
||||
if(sprX+sprSize.x<0) continue; // fully out of screen
|
||||
lg += sprX;
|
||||
x = -sprX;
|
||||
sprX = 0;
|
||||
// sprite portion out of the screen (RIGHT)
|
||||
} else if(sprX+sprSize.x >= 256)
|
||||
lg = 256 - sprX;
|
||||
|
||||
|
||||
y = l - sprY; /* get the y line within sprite coords */
|
||||
prio = spriteInfo->Priority;
|
||||
|
||||
|
||||
if (!compute_sprite_vars(spriteInfo, l, &sprSize, &sprX, &sprY, &x, &y, &lg, &xdir))
|
||||
continue;
|
||||
|
||||
if (spriteInfo->RotScale & 1)
|
||||
compute_sprite_rotoscale(gpu, spriteInfo,
|
||||
&rotScaleA, &rotScaleB, &rotScaleC, &rotScaleD);
|
||||
|
||||
// switch TOP<-->BOTTOM
|
||||
if (spriteInfo->VFlip)
|
||||
y = sprSize.y - y -1;
|
||||
|
||||
// switch LEFT<-->RIGHT
|
||||
if (spriteInfo->HFlip) {
|
||||
x = sprSize.x -x -1;
|
||||
xdir = -1;
|
||||
} else {
|
||||
xdir = 1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (spriteInfo->Mode == 2) {
|
||||
if (spriteInfo->Depth)
|
||||
src = gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8);
|
||||
|
@ -1336,13 +1291,13 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
spriteInfo->Depth, lg, sprX, x, xdir);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (spriteInfo->Mode == 3) /* sprite is in BMP format */
|
||||
{
|
||||
/* sprMemory + sprBlock + 16Bytes per line (8pixels a 2 bytes) */
|
||||
src = (gpu->sprMem) + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBlock);
|
||||
/* sprMemory + sprBoundary + 16Bytes per line (8pixels a 2 bytes) */
|
||||
src = (gpu->sprMem) + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBoundary);
|
||||
|
||||
render_sprite_BMP (gpu, l, dst, src,
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
@ -1357,7 +1312,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
else
|
||||
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400;
|
||||
|
||||
render_sprite_256 (gpu, l, dst, src, pal,
|
||||
render_sprite_256 (gpu, l, dst, src, (u16*)pal,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
@ -1380,68 +1335,23 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
|
||||
for(i = 0; i<nbShow; ++i, --spriteInfo)
|
||||
{
|
||||
s32 sprX;
|
||||
s32 sprY;
|
||||
s32 x = 0;
|
||||
u32 lg;
|
||||
size sprSize;
|
||||
s32 y;
|
||||
u8 prio;
|
||||
u8 * src;
|
||||
u8 * pal;
|
||||
u16 i, j;
|
||||
int xdir, block;
|
||||
|
||||
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD ;
|
||||
if (spriteInfo->RotScale & 1) {
|
||||
/* if we need to do rotscale, gather its parameters */
|
||||
/* http://nocash.emubase.de/gbatek.htm#lcdobjoamrotationscalingparameters */
|
||||
rotScaleA = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x06,0) ;
|
||||
rotScaleB = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x0E,0) ;
|
||||
rotScaleC = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x16,0) ;
|
||||
rotScaleD = T1ReadWord(gpu->oam + spriteInfo->RotScalIndex*0x20 + 0x1E,0) ;
|
||||
} ;
|
||||
s32 sprX, sprY, x, y, lg;
|
||||
int xdir;
|
||||
u8 prio, * src, * pal;
|
||||
u16 i,j;
|
||||
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD;
|
||||
int block;
|
||||
|
||||
sprX = (spriteInfo->X<<23)>>23;
|
||||
sprY = spriteInfo->Y;
|
||||
sprSize = sprSizeTab[spriteInfo->Size][spriteInfo->Shape];
|
||||
|
||||
lg = sprSize.x;
|
||||
prio = spriteInfo->Priority;
|
||||
|
||||
if(sprY>192)
|
||||
sprY = (s32)((s8)(spriteInfo->Y));
|
||||
|
||||
if( (spriteInfo->RotScale == 2) ||
|
||||
(l<sprY)||(l>=sprY+sprSize.y) ||
|
||||
(sprX==256) )
|
||||
if (!compute_sprite_vars(spriteInfo, l, &sprSize, &sprX, &sprY, &x, &y, &lg, &xdir))
|
||||
continue;
|
||||
|
||||
// sprite portion out of the screen (LEFT)
|
||||
if(sprX<0)
|
||||
{
|
||||
if(sprX+sprSize.x<0) continue; // fully out of screen
|
||||
lg += sprX;
|
||||
x = -sprX;
|
||||
sprX = 0;
|
||||
// sprite portion out of the screen (RIGHT)
|
||||
} else if(sprX+sprSize.x >= 256)
|
||||
lg = 256 - sprX;
|
||||
|
||||
y = l - sprY;
|
||||
prio = spriteInfo->Priority;
|
||||
|
||||
// switch TOP<-->BOTTOM
|
||||
if (spriteInfo->VFlip)
|
||||
y = sprSize.y - y -1;
|
||||
|
||||
// switch LEFT<-->RIGHT
|
||||
if (spriteInfo->HFlip) {
|
||||
x = sprSize.x -x -1;
|
||||
xdir = -1;
|
||||
} else {
|
||||
xdir = 1;
|
||||
}
|
||||
#if 1
|
||||
if (spriteInfo->RotScale & 1)
|
||||
compute_sprite_rotoscale(gpu, spriteInfo,
|
||||
&rotScaleA, &rotScaleB, &rotScaleC, &rotScaleD);
|
||||
|
||||
if (spriteInfo->Mode == 2) {
|
||||
if (spriteInfo->Depth)
|
||||
src = gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8);
|
||||
|
@ -1451,12 +1361,15 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
spriteInfo->Depth, lg, sprX, x, xdir);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (spriteInfo->Mode == 3) /* sprite is in BMP format */
|
||||
{
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1);
|
||||
if (gpu->dispCnt.bits.OBJ_BMP_2D_dim) // 256*256
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1);
|
||||
else // 128 * 512
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1);
|
||||
|
||||
render_sprite_BMP (gpu, l, dst, src,
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
@ -1467,7 +1380,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
src = gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8);
|
||||
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400;
|
||||
|
||||
render_sprite_256 (gpu, l, dst, src, pal,
|
||||
render_sprite_256 (gpu, l, dst, src, (u16*)pal,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
|
|
@ -58,6 +58,31 @@ extern "C" {
|
|||
#define ADDRESS_STEP_32KB 0x08000
|
||||
#define ADDRESS_STEP_64kB 0x10000
|
||||
|
||||
struct _TILEENTRY
|
||||
{
|
||||
/* 0*/ unsigned TileNum:10;
|
||||
/*12*/ unsigned HFlip:1; // HORIZONTAL FLIP (left<-->right)
|
||||
/*13*/ unsigned VFlip:1; // VERTICAL FLIP (top<-->bottom)
|
||||
/*14*/ unsigned Palette:4;
|
||||
};
|
||||
typedef union
|
||||
{
|
||||
struct _TILEENTRY bits;
|
||||
u32 val;
|
||||
} TILEENTRY;
|
||||
|
||||
struct _ROTOCOORD
|
||||
{
|
||||
/* 0*/ unsigned Fraction:8;
|
||||
/* 8*/ unsigned Integer:19;
|
||||
/*27*/ unsigned Sign:1;
|
||||
/*28*/ unsigned :4;
|
||||
};
|
||||
typedef union
|
||||
{
|
||||
struct _ROTOCOORD bits;
|
||||
u32 val;
|
||||
} ROTOCOORD;
|
||||
|
||||
/*
|
||||
this structure is for display control,
|
||||
|
@ -106,6 +131,30 @@ typedef union
|
|||
} DISPCNT;
|
||||
#define BGxENABLED(cnt,num) ((num<8)? ((cnt.val>>8) & num):0)
|
||||
|
||||
// source:
|
||||
// http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||
struct _DISPCAPCNT
|
||||
{
|
||||
/* 0*/ unsigned BlendFactor_A:5; // 0..16 = Blending Factor for Source A
|
||||
/* 5*/ unsigned :3; //
|
||||
/* 8*/ unsigned BlendFactor_B:5; // 0..16 = Blending Factor for Source B
|
||||
/*13*/ unsigned :3; //
|
||||
/*16*/ unsigned VRAM_Write_Block:2; // 0..3 = VRAM A..D
|
||||
/*18*/ unsigned VRAM_Write_Offset:2; // n x 0x08000
|
||||
/*20*/ unsigned Capture_Size:2; // 0=128x128, 1=256x64, 2=256x128, 3=256x192 dots
|
||||
/*22*/ unsigned :2; //
|
||||
/*24*/ unsigned Source_A:1; // 0=Graphics Screen BG+3D+OBJ, 1=3D Screen
|
||||
/*25*/ unsigned Source_B:1; // 0=VRAM, 1=Main Memory Display FIFO
|
||||
/*26*/ unsigned VRAM_Read_Offset:2; // n x 0x08000
|
||||
/*28*/ unsigned :1; //
|
||||
/*29*/ unsigned Capture_Source:2; // 0=Source A, 1=Source B, 2/3=Sources A+B blended
|
||||
/*31*/ unsigned Capture_Enable:1; // 0=Disable/Ready, 1=Enable/Busy
|
||||
};
|
||||
typedef union
|
||||
{
|
||||
struct _DISPCAPCNT bits;
|
||||
u32 val;
|
||||
} DISPCAPCNT;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -180,6 +229,7 @@ struct _BGxCNT
|
|||
// large : 512x1024 1024x512 - -
|
||||
};
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _BGxCNT bits;
|
||||
|
@ -337,6 +387,7 @@ typedef struct _GPU GPU;
|
|||
struct _GPU
|
||||
{
|
||||
DISPCNT dispCnt;
|
||||
DISPCAPCNT dispCapCnt;
|
||||
BGxCNT bgCnt[4];
|
||||
MASTER_BRIGHT masterBright;
|
||||
BOOL LayersEnable[5];
|
||||
|
@ -378,8 +429,8 @@ struct _GPU
|
|||
|
||||
OAM * oam;
|
||||
u8 * sprMem;
|
||||
u8 sprBlock;
|
||||
u8 sprBMPBlock;
|
||||
u8 sprBoundary;
|
||||
u8 sprBMPBoundary;
|
||||
u8 sprBMPMode;
|
||||
u32 sprEnable ;
|
||||
|
||||
|
@ -428,8 +479,13 @@ void Screen_DeInit(void);
|
|||
|
||||
extern MMU_struct MMU;
|
||||
|
||||
static INLINE void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) {
|
||||
gpu->dispCapCnt.val = val;
|
||||
}
|
||||
|
||||
static INLINE void GPU_ligne(Screen * screen, u16 l)
|
||||
{
|
||||
struct _DISPCAPCNT * capcnt;
|
||||
GPU * gpu = screen->gpu;
|
||||
u8 * dst = GPU_screen + (screen->offset + l) * 512;
|
||||
u8 * mdst = GPU_screen + (MainScreen.offset + l) * 512;
|
||||
|
@ -555,6 +611,98 @@ static INLINE void GPU_ligne(Screen * screen, u16 l)
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME !!!
|
||||
/* capture */
|
||||
capcnt = &gpu->dispCapCnt.bits;
|
||||
if (0 & capcnt->Capture_Enable)
|
||||
{
|
||||
u16 * srcA, * srcB, *vram;
|
||||
u32 c; u8 vram_bank;
|
||||
COLOR color, colA, colB;
|
||||
u16 ilast= 128;
|
||||
if (capcnt->Capture_Size) ilast = 256;
|
||||
|
||||
vram = (u16*)(ARM9Mem.ARM9_ABG
|
||||
+ MMU.vram_mode[capcnt->VRAM_Write_Block] * 0x20000
|
||||
+ capcnt->VRAM_Write_Offset * 0x08000);
|
||||
|
||||
// I dunno yet how to do for 3D
|
||||
if (!capcnt->Source_A)
|
||||
srcA = (u16*)dst;
|
||||
|
||||
if (!capcnt->Source_B) {
|
||||
vram_bank = gpu->dispCnt.bits.VRAM_Block ;
|
||||
if (MMU.vram_mode[vram_bank] & 4) {
|
||||
srcB = (u16*)(ARM9Mem.ARM9_LCD
|
||||
+ (MMU.vram_mode[vram_bank] & 3) * 0x20000
|
||||
+ capcnt->VRAM_Read_Offset * 0x08000);
|
||||
} else {
|
||||
srcB = (u16*)(ARM9Mem.ARM9_ABG
|
||||
+ MMU.vram_mode[vram_bank] * 0x20000
|
||||
+ capcnt->VRAM_Read_Offset * 0x08000);
|
||||
}
|
||||
}
|
||||
|
||||
printf("capture source %d\n",capcnt->Capture_Source);
|
||||
|
||||
switch(capcnt->Capture_Source) {
|
||||
case 0: // only source A
|
||||
if (!capcnt->Source_A) {
|
||||
srcA = (u16*)dst;
|
||||
for (i=0; i<ilast; i++) {
|
||||
vram[i] = srcA[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // only source B
|
||||
if (capcnt->Source_B) {
|
||||
for (i=0; i<ilast;) {
|
||||
c = FIFOValue(MMU.fifos + MAIN_MEMORY_DISP_FIFO);
|
||||
vram[i] = c&0xFFFF; i++;
|
||||
vram[i] = c>>16; i++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<ilast; i++) {
|
||||
vram[i] = srcB[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // blend A + B
|
||||
if (capcnt->Source_B) {
|
||||
for (i=0; i<ilast;) {
|
||||
c = FIFOValue(MMU.fifos + MAIN_MEMORY_DISP_FIFO);
|
||||
colA.val = c&0xFFFF;
|
||||
colB.val = srcB[i];
|
||||
#define FORMULA(field) \
|
||||
color.bits.field = ((colA.bits.field * colA.bits.alpha * capcnt->BlendFactor_A) + (colB.bits.field * colB.bits.alpha * capcnt->BlendFactor_B)) / 16;
|
||||
FORMULA(red)
|
||||
FORMULA(green)
|
||||
FORMULA(blue)
|
||||
vram[i] = color.val;
|
||||
i++;
|
||||
colA.val = c >> 16;
|
||||
colB.val = srcB[i];
|
||||
FORMULA(red)
|
||||
FORMULA(green)
|
||||
FORMULA(blue)
|
||||
vram[i] = color.val;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<ilast; i++) {
|
||||
colA.val = srcA[i];
|
||||
colB.val = srcB[i];
|
||||
FORMULA(red)
|
||||
FORMULA(green)
|
||||
FORMULA(blue)
|
||||
vram[i] = color.val;
|
||||
}
|
||||
#undef FORMULA
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* end of capture */
|
||||
|
||||
// Apply final brightness adjust (MASTER_BRIGHT)
|
||||
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideo (Under MASTER_BRIGHTNESS)
|
||||
|
@ -716,7 +864,6 @@ void GPU_setMASTER_BRIGHT (GPU *gpu, u16 v);
|
|||
|
||||
void GPU_remove(GPU *, u8 num);
|
||||
void GPU_addBack(GPU *, u8 num);
|
||||
void GPU_toggleOBJ(GPU *, u8 disp);
|
||||
|
||||
int GPU_ChangeGraphicsCore(int coreid);
|
||||
|
||||
|
|
|
@ -1700,14 +1700,12 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
|
|||
T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, v);
|
||||
}
|
||||
return;
|
||||
/*
|
||||
case REG_DISPA_DISPCAPCNT :
|
||||
case REG_DISPA_DISPCAPCNT :
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
GPU_set_DISPCAPCNT(MainScreen.gpu,val);
|
||||
}
|
||||
return;
|
||||
*/
|
||||
case REG_DISPB_DISPCNT+2 :
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue