- Reverted to 1.88 as the newer versions crashed all the time. Please, avoid committing broken code, test it before and only commit debugged and functional code
This commit is contained in:
parent
7071f0d35c
commit
6c2d61323e
|
@ -148,15 +148,11 @@ void GPU_resortBGs(GPU *gpu)
|
|||
memset(gpu->sprWin[i],0, 256);
|
||||
|
||||
// we don't need to check for windows here...
|
||||
// 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);
|
||||
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;
|
||||
|
||||
// KISS ! lower priority first, if same then lower num
|
||||
for (i=0;i<NB_PRIORITIES;i++) {
|
||||
|
@ -224,29 +220,26 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
|
|||
if(cnt->OBJ_Tile_1D)
|
||||
{
|
||||
/* 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 ;
|
||||
/* TODO: better comment (and understanding btw 8S) */
|
||||
gpu->sprBlock = 5 + cnt->OBJ_Tile_1D_Bound ;
|
||||
if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3))
|
||||
{
|
||||
gpu->sprBoundary = 7;
|
||||
gpu->sprBlock = 7;
|
||||
}
|
||||
gpu->spriteRender = sprite1D;
|
||||
} else {
|
||||
/* 2d sprite mapping */
|
||||
// boundary : 32k
|
||||
gpu->sprBoundary = 5;
|
||||
gpu->sprBlock = 5;
|
||||
gpu->spriteRender = sprite2D;
|
||||
}
|
||||
|
||||
if(cnt->OBJ_BMP_1D_Bound && (gpu->core == GPU_MAIN))
|
||||
{
|
||||
gpu->sprBMPBoundary = 8;
|
||||
gpu->sprBMPBlock = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpu->sprBMPBoundary = 7;
|
||||
gpu->sprBMPBlock = 7;
|
||||
}
|
||||
|
||||
gpu->sprEnable = cnt->OBJ_Enable;
|
||||
|
@ -302,18 +295,19 @@ void GPU_setBGProp(GPU * gpu, u16 num, u16 p)
|
|||
|
||||
void GPU_remove(GPU * gpu, u8 num)
|
||||
{
|
||||
if (num == 4) gpu->dispOBJ = 0;
|
||||
else gpu->dispBG[num] = 0;
|
||||
gpu->dispBG[num] = 0;
|
||||
GPU_resortBGs(gpu);
|
||||
}
|
||||
|
||||
void GPU_addBack(GPU * gpu, u8 num)
|
||||
{
|
||||
if (num == 4) gpu->dispOBJ = 1;
|
||||
else gpu->dispBG[num] = 1;
|
||||
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)
|
||||
{
|
||||
|
@ -672,8 +666,6 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
u8 * pal;
|
||||
u16 yoff;
|
||||
u16 x;
|
||||
u8 line_dir = 1;
|
||||
u8 pt_xor = 0;
|
||||
|
||||
if(tmp>31)
|
||||
{
|
||||
|
@ -697,7 +689,6 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
for(x = 0; x < LG;)
|
||||
{
|
||||
u8 pt = 0, save = 0;
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 *line;
|
||||
|
@ -716,36 +707,60 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
if (c) renderline_setFinalColor(gpu,0,num,dst,T1ReadWord(pal, ((c) + ((mapinfovalue>>12)&0xF) * m) << 1),x,Y) ; \
|
||||
dst += 2; x++; xoff++;
|
||||
|
||||
|
||||
if((mapinfovalue) & 0x400)
|
||||
{
|
||||
u8 pt = 0 ;
|
||||
u8 save = 0;
|
||||
|
||||
line += 3 - ((xoff&7)>>1);
|
||||
line_dir = -1;
|
||||
pt_xor = 0;
|
||||
} else {
|
||||
line += ((xoff&7)>>1);
|
||||
line_dir = 1;
|
||||
pt_xor = 1;
|
||||
}
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
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 ;
|
||||
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)^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++ ;
|
||||
}
|
||||
} else {
|
||||
u8 pt = 0 ;
|
||||
u8 save = 0;
|
||||
line += ((xoff&7)>>1);
|
||||
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
if (!(pt % mw)) { /* only update the color we draw every n 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++ ;
|
||||
}
|
||||
RENDERL(save,0x10)
|
||||
line+=line_dir; pt++ ;
|
||||
}
|
||||
}
|
||||
} else { /* no mosaic mode */
|
||||
|
@ -771,19 +786,19 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
if((mapinfovalue) & 0x400)
|
||||
{
|
||||
line += 3 - ((xoff&7)>>1);
|
||||
line_dir = -1;
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
RENDERL(((*line)>>4),0x10)
|
||||
RENDERL(((*line)&0xF),0x10)
|
||||
line += line_dir;
|
||||
line--;
|
||||
}
|
||||
} else {
|
||||
line += ((xoff&7)>>1);
|
||||
line_dir = 1;
|
||||
for(; x < xfin; ) {
|
||||
// XXX
|
||||
RENDERL(((*line)&0xF),0x10)
|
||||
RENDERL(((*line)>>4),0x10)
|
||||
line += line_dir;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -792,35 +807,44 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
}
|
||||
if(!gpu->dispCnt.bits.ExBGxPalette_Enable) /* color: no extended palette */
|
||||
{
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 *line;
|
||||
u16 xfin;
|
||||
tmp = ((xoff&(lg-1))>>3);
|
||||
mapinfo = map + (tmp & 31) * 2;
|
||||
mapinfovalue;
|
||||
|
||||
if(tmp > 31) mapinfo += 32*32*2;
|
||||
|
||||
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)
|
||||
yoff = ((YBG&7)<<3);
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
for(x = 0; x < LG;)
|
||||
{
|
||||
line += (7 - (xoff&7));
|
||||
line_dir = -1;
|
||||
} else {
|
||||
line += (xoff&7);
|
||||
line_dir = 1;
|
||||
}
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0)
|
||||
line += line_dir;
|
||||
u8 * mapinfo;
|
||||
u16 mapinfovalue;
|
||||
u8 *line;
|
||||
u16 xfin;
|
||||
tmp = ((xoff&(lg-1))>>3);
|
||||
mapinfo = map + (tmp & 31) * 2;
|
||||
mapinfovalue;
|
||||
|
||||
if(tmp > 31) mapinfo += 32*32*2;
|
||||
|
||||
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)
|
||||
{
|
||||
line += (7 - (xoff&7));
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0)
|
||||
line--;
|
||||
}
|
||||
} else
|
||||
{
|
||||
line += (xoff&7);
|
||||
for(; x < xfin; )
|
||||
{
|
||||
RENDERL((*line),0)
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -852,150 +876,163 @@ INLINE void renderline_textBG(GPU * gpu, u8 num, u8 * DST, u32 Y, u16 XBG, u16 Y
|
|||
if((mapinfovalue)& 0x400)
|
||||
{
|
||||
line += (7 - (xoff&7));
|
||||
line_dir = -1;
|
||||
} else {
|
||||
line += (xoff&7);
|
||||
line_dir = 1;
|
||||
}
|
||||
for(; x < xfin; )
|
||||
for(; x < xfin;)
|
||||
{
|
||||
/* this is was adapted */
|
||||
RENDERL((*line),0x100)
|
||||
line--;
|
||||
}
|
||||
} else
|
||||
{
|
||||
RENDERL((*line),0x100)
|
||||
line += line_dir;
|
||||
line += (xoff&7);
|
||||
for(; x < xfin; )
|
||||
{
|
||||
/* this is was adapted */
|
||||
RENDERL((*line),0x100)
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef RENDERL
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
tileindex = map[(auxX + auxY * lg)>>3];
|
||||
x = (auxX&7); y = (auxY&7);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
s32 x = X + (s32)PB*(s32)H;
|
||||
s32 y = 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;
|
||||
}
|
||||
|
||||
s32 dx = (s32)PA;
|
||||
s32 dy = (s32)PC;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
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 * 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;
|
||||
|
||||
u8 *map, *tile, *pal;
|
||||
u8 * dst = DST;
|
||||
u8 * map;
|
||||
u16 mapinfo, i;
|
||||
u8 coul;
|
||||
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 :
|
||||
// 16 bit bgmap entries
|
||||
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; \
|
||||
}
|
||||
map = gpu->BG_map_ram[num];
|
||||
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);
|
||||
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);
|
||||
})
|
||||
|
||||
}
|
||||
return;
|
||||
case 2 :
|
||||
// 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);
|
||||
{
|
||||
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);
|
||||
})
|
||||
}
|
||||
return;
|
||||
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);
|
||||
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);
|
||||
})
|
||||
}
|
||||
return;
|
||||
}
|
||||
#undef LOOP
|
||||
}
|
||||
}
|
||||
|
||||
void lineText(GPU * gpu, u8 num, u16 l, u8 * DST)
|
||||
|
@ -1075,6 +1112,7 @@ 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)
|
||||
}
|
||||
|
@ -1213,96 +1251,82 @@ 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->sprBoundary;
|
||||
u8 block = gpu->sprBlock;
|
||||
u16 i;
|
||||
|
||||
for(i = 0; i<nbShow; ++i, --spriteInfo) /* check all sprites */
|
||||
{
|
||||
s32 sprX;
|
||||
s32 sprY;
|
||||
s32 x = 0;
|
||||
u32 lg;
|
||||
size sprSize;
|
||||
s32 sprX, sprY, x, y, lg;
|
||||
int xdir;
|
||||
u8 prio, * src, * pal;
|
||||
s32 y;
|
||||
u8 prio;
|
||||
u8 * src;
|
||||
u8 * pal;
|
||||
u16 i,j;
|
||||
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD;
|
||||
int xdir;
|
||||
|
||||
prio = spriteInfo->Priority;
|
||||
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) ;
|
||||
} ;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
@ -1312,13 +1336,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 + sprBoundary + 16Bytes per line (8pixels a 2 bytes) */
|
||||
src = (gpu->sprMem) + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBoundary);
|
||||
/* sprMemory + sprBlock + 16Bytes per line (8pixels a 2 bytes) */
|
||||
src = (gpu->sprMem) + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBlock);
|
||||
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src,
|
||||
render_sprite_BMP (gpu, l, dst, src,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
@ -1333,7 +1357,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, (u16*)pal,
|
||||
render_sprite_256 (gpu, l, dst, src, pal,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
@ -1356,23 +1380,68 @@ 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 sprX, sprY, x, y, lg;
|
||||
int xdir;
|
||||
u8 prio, * src, * pal;
|
||||
u16 i,j;
|
||||
u16 rotScaleA,rotScaleB,rotScaleC,rotScaleD;
|
||||
int block;
|
||||
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) ;
|
||||
} ;
|
||||
|
||||
prio = spriteInfo->Priority;
|
||||
sprX = (spriteInfo->X<<23)>>23;
|
||||
sprY = spriteInfo->Y;
|
||||
sprSize = sprSizeTab[spriteInfo->Size][spriteInfo->Shape];
|
||||
|
||||
lg = sprSize.x;
|
||||
|
||||
if (!compute_sprite_vars(spriteInfo, l, &sprSize, &sprX, &sprY, &x, &y, &lg, &xdir))
|
||||
if(sprY>192)
|
||||
sprY = (s32)((s8)(spriteInfo->Y));
|
||||
|
||||
if( (spriteInfo->RotScale == 2) ||
|
||||
(l<sprY)||(l>=sprY+sprSize.y) ||
|
||||
(sprX==256) )
|
||||
continue;
|
||||
|
||||
if (spriteInfo->RotScale & 1)
|
||||
compute_sprite_rotoscale(gpu, spriteInfo,
|
||||
&rotScaleA, &rotScaleB, &rotScaleC, &rotScaleD);
|
||||
|
||||
// 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->Mode == 2) {
|
||||
if (spriteInfo->Depth)
|
||||
src = gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8);
|
||||
|
@ -1382,15 +1451,12 @@ 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 */
|
||||
{
|
||||
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);
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1);
|
||||
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src,
|
||||
render_sprite_BMP (gpu, l, dst, src,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
@ -1401,7 +1467,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, (u16*)pal,
|
||||
render_sprite_256 (gpu, l, dst, src, pal,
|
||||
prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue