mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
md vdp, fix sprite parsing (done on previous line)
This commit is contained in:
parent
e5a1d4c5f1
commit
ac89144969
3 changed files with 20 additions and 16 deletions
26
pico/draw.c
26
pico/draw.c
|
@ -63,7 +63,7 @@ static u32 HighCacheA[41*2+1]; // caches for high layers
|
|||
static u32 HighCacheB[41*2+1];
|
||||
static s32 HighPreSpr[80*2+1]; // slightly preprocessed sprites
|
||||
|
||||
u32 VdpSATCache[128]; // VDP sprite cache (1st 32 sprite attr bits)
|
||||
u32 VdpSATCache[2*128]; // VDP sprite cache (1st 32 sprite attr bits)
|
||||
|
||||
// NB don't change any defines without checking their usage in ASM
|
||||
|
||||
|
@ -1401,7 +1401,7 @@ static void DrawSpritesForced(unsigned char *sprited)
|
|||
// Index + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: vert./horiz. size
|
||||
// Index + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8
|
||||
|
||||
static NOINLINE void PrepareSprites(int max_lines)
|
||||
static NOINLINE void ParseSprites(int max_lines)
|
||||
{
|
||||
const struct PicoVideo *pvid=&Pico.video;
|
||||
const struct PicoEState *est=&Pico.est;
|
||||
|
@ -1411,6 +1411,12 @@ static NOINLINE void PrepareSprites(int max_lines)
|
|||
int max_sprites = 80, max_width = 328;
|
||||
int max_line_sprites = 20; // 20 sprites, 40 tiles
|
||||
|
||||
// SAT scanning is one line ahead, but don't overshoot. Technically, SAT
|
||||
// parsing for line 0 is on the last line of the previous frame.
|
||||
int first_line = Pico.est.DrawScanline + !!Pico.est.DrawScanline;
|
||||
if (max_lines > rendlines-1)
|
||||
max_lines = rendlines-1;
|
||||
|
||||
if (!(Pico.video.reg[12]&1))
|
||||
max_sprites = 64, max_line_sprites = 16, max_width = 264;
|
||||
if (*est->PicoOpt & POPT_DIS_SPRITE_LIM)
|
||||
|
@ -1422,7 +1428,7 @@ static NOINLINE void PrepareSprites(int max_lines)
|
|||
if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode
|
||||
table<<=8; // Get sprite table address/2
|
||||
|
||||
for (u = est->DrawScanline; u < max_lines; u++)
|
||||
for (u = first_line; u <= max_lines; u++)
|
||||
*((int *)&HighLnSpr[u][0]) = 0;
|
||||
|
||||
for (u = 0; u < max_sprites && link < max_sprites; u++)
|
||||
|
@ -1434,7 +1440,7 @@ static NOINLINE void PrepareSprites(int max_lines)
|
|||
|
||||
// parse sprite info. the 1st half comes from the VDPs internal cache,
|
||||
// the 2nd half is read from VRAM
|
||||
code = CPU_LE2(VdpSATCache[link]); // normally same as sprite[0]
|
||||
code = CPU_LE2(VdpSATCache[2*link]); // normally same as sprite[0]
|
||||
sy = (code&0x1ff)-0x80;
|
||||
hv = (code>>24)&0xf;
|
||||
height = (hv&3)+1;
|
||||
|
@ -1444,7 +1450,7 @@ static NOINLINE void PrepareSprites(int max_lines)
|
|||
sx = (code2>>16)&0x1ff;
|
||||
sx -= 0x78; // Get X coordinate + 8
|
||||
|
||||
if (sy < max_lines && sy + (height<<3) >= est->DrawScanline) // sprite onscreen (y)?
|
||||
if (sy <= max_lines && sy + (height<<3) >= first_line) // sprite onscreen (y)?
|
||||
{
|
||||
int entry, y, w, sx_min, onscr_x, maybe_op = 0;
|
||||
|
||||
|
@ -1454,8 +1460,8 @@ static NOINLINE void PrepareSprites(int max_lines)
|
|||
maybe_op = SPRL_MAY_HAVE_OP;
|
||||
|
||||
entry = ((pd - HighPreSpr) / 2) | ((code2>>8)&0x80);
|
||||
y = (sy >= est->DrawScanline) ? sy : est->DrawScanline;
|
||||
for (; y < sy + (height<<3) && y < max_lines; y++)
|
||||
y = (sy >= first_line) ? sy : first_line;
|
||||
for (; y < sy + (height<<3) && y <= max_lines; y++)
|
||||
{
|
||||
unsigned char *p = &HighLnSpr[y][0];
|
||||
int cnt = p[0];
|
||||
|
@ -1501,7 +1507,7 @@ static NOINLINE void PrepareSprites(int max_lines)
|
|||
*pd = 0;
|
||||
|
||||
#if 0
|
||||
for (u = 0; u < max_lines; u++)
|
||||
for (u = first_line; u <= max_lines; u++)
|
||||
{
|
||||
int y;
|
||||
printf("c%03i: f %x c %2i/%2i w %2i: ", u, HighLnSpr[u][1],
|
||||
|
@ -1982,9 +1988,9 @@ void PicoDrawSync(int to, int blank_last_line)
|
|||
if (to > 223)
|
||||
to = 223;
|
||||
}
|
||||
if (est->DrawScanline <= to - blank_last_line && (est->rendstatus &
|
||||
if (est->DrawScanline <= to && (est->rendstatus &
|
||||
(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES|PDRAW_PARSE_SPRITES)))
|
||||
PrepareSprites(to - blank_last_line + 1);
|
||||
ParseSprites(to + 1);
|
||||
|
||||
for (line = est->DrawScanline; line < to; line++)
|
||||
PicoLine(line, offs, sh, bgc);
|
||||
|
|
|
@ -705,7 +705,7 @@ extern unsigned char *HighColBase;
|
|||
extern int HighColIncrement;
|
||||
extern void *DrawLineDestBase;
|
||||
extern int DrawLineDestIncrement;
|
||||
extern u32 VdpSATCache[128];
|
||||
extern u32 VdpSATCache[2*128];
|
||||
|
||||
// draw2.c
|
||||
void PicoDraw2SetOutBuf(void *dest, int incr);
|
||||
|
@ -890,9 +890,7 @@ static __inline void UpdateSAT(u32 a, u32 d)
|
|||
unsigned num = (a^SATaddr) >> 3;
|
||||
|
||||
Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES;
|
||||
if (!(a & 4) && num < 128) {
|
||||
((u16 *)&VdpSATCache[num])[(a&3) >> 1] = d;
|
||||
}
|
||||
((u16 *)&VdpSATCache[2*num])[(a&7) >> 1] = d;
|
||||
}
|
||||
static __inline void VideoWriteVRAM(u32 a, u16 d)
|
||||
{
|
||||
|
|
|
@ -1104,8 +1104,8 @@ void PicoVideoCacheSAT(int load)
|
|||
SATaddr &= ~0x200, SATmask &= ~0x200; // H40, zero lowest SAT bit
|
||||
|
||||
// rebuild SAT cache XXX wrong since cache and memory can differ
|
||||
for (l = 0; load && l < 80; l++) {
|
||||
u16 addr = SATaddr + l*8;
|
||||
for (l = 0; load && l < 2*80; l ++) {
|
||||
u16 addr = SATaddr + l*4;
|
||||
((u16 *)VdpSATCache)[l*2 ] = PicoMem.vram[(addr>>1) ];
|
||||
((u16 *)VdpSATCache)[l*2 + 1] = PicoMem.vram[(addr>>1) + 1];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue