mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
sms, improve vdp (mode 1, collision code cleanup)
This commit is contained in:
parent
280bfc3ca7
commit
4dbd5223b1
1 changed files with 90 additions and 32 deletions
108
pico/mode4.c
108
pico/mode4.c
|
@ -27,18 +27,21 @@ static int CollisionDetect(u8 *mb, u16 sx, unsigned int pack, int zoomed)
|
||||||
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff };
|
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff };
|
||||||
u8 *mp = mb + (sx>>3);
|
u8 *mp = mb + (sx>>3);
|
||||||
unsigned col, m;
|
unsigned col, m;
|
||||||
// create a pixel bitmap of the sprite pixels from the 4 bitplanes in pack
|
|
||||||
pack = ((pack | (pack>>16)) | ((pack | (pack>>16))>>8)) & 0xff;
|
// check sprite map for collision and update map with current sprite
|
||||||
if (zoomed) pack = morton[pack&0x0f] | (morton[(pack>>4)&0x0f] << 8);
|
if (!zoomed) { // 8 sprite pixels
|
||||||
// get the corresponding data from the sprite map
|
|
||||||
m = mp[0] | (mp[1]<<8);
|
m = mp[0] | (mp[1]<<8);
|
||||||
if (zoomed) m |= (mp[2]<<16);
|
col = m & (pack<<(sx&7)); // collision if current sprite overlaps sprite map
|
||||||
// collision if bits in pixel bitmap overlap bits in sprite map
|
|
||||||
col = m & (pack<<(sx&7));
|
|
||||||
// update sprite map data with our pixel bitmap
|
|
||||||
m |= pack<<(sx&7);
|
m |= pack<<(sx&7);
|
||||||
mp[0] = m, mp[1] = m>>8;
|
mp[0] = m, mp[1] = m>>8;
|
||||||
if (zoomed) mp[2] = m>>16;
|
} else { // 16 sprite pixels in zoom mode
|
||||||
|
pack = morton[pack&0x0f] | (morton[(pack>>4)&0x0f] << 8);
|
||||||
|
m = mp[0] | (mp[1]<<8) | (mp[2]<<16);
|
||||||
|
col = m & (pack<<(sx&7));
|
||||||
|
m |= pack<<(sx&7);
|
||||||
|
mp[0] = m, mp[1] = m>>8, mp[2] = m>>16;
|
||||||
|
}
|
||||||
|
|
||||||
// invisible overscan area, not tested for collision
|
// invisible overscan area, not tested for collision
|
||||||
mb[0] = mb[33] = 0;
|
mb[0] = mb[33] = 0;
|
||||||
return col;
|
return col;
|
||||||
|
@ -53,7 +56,7 @@ static void TileBGM4(u16 sx, int pal)
|
||||||
pd[0] = pd[1] = pal * 0x01010101;
|
pd[0] = pd[1] = pal * 0x01010101;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8 pixels are arranged to have 1 bit in each byte of a 32 bit word. To pull
|
// 8 pixels are arranged are arranged in 4 bitplanes in a 32 bit word. To pull
|
||||||
// the 4 bitplanes together multiply with each bit distance (multiples of 1<<7)
|
// the 4 bitplanes together multiply with each bit distance (multiples of 1<<7)
|
||||||
#define PLANAR_PIXELBG(x,p) \
|
#define PLANAR_PIXELBG(x,p) \
|
||||||
t = (pack>>(7-p)) & 0x01010101; \
|
t = (pack>>(7-p)) & 0x01010101; \
|
||||||
|
@ -191,6 +194,8 @@ static void DrawSpritesM4(int scanline)
|
||||||
pack = CPU_LE2(*(u32 *)(PicoMem.vram + sprites_addr[s]));
|
pack = CPU_LE2(*(u32 *)(PicoMem.vram + sprites_addr[s]));
|
||||||
if (zoomed) TileDoubleSprM4(sprites_x[s], pack, 0x10);
|
if (zoomed) TileDoubleSprM4(sprites_x[s], pack, 0x10);
|
||||||
else TileNormSprM4(sprites_x[s], pack, 0x10);
|
else TileNormSprM4(sprites_x[s], pack, 0x10);
|
||||||
|
// make sprite pixel map by merging the 4 bitplanes
|
||||||
|
pack = ((pack | (pack>>16)) | ((pack | (pack>>16))>>8)) & 0xff;
|
||||||
if (!m) m = CollisionDetect(mb, sprites_x[s], pack, zoomed);
|
if (!m) m = CollisionDetect(mb, sprites_x[s], pack, zoomed);
|
||||||
}
|
}
|
||||||
if (m)
|
if (m)
|
||||||
|
@ -222,7 +227,7 @@ static void DrawStripM4(const u16 *nametab, int cells_dx, int tilex_ty)
|
||||||
pal = (code>>7) & 0x30; // prio | palette select
|
pal = (code>>7) & 0x30; // prio | palette select
|
||||||
}
|
}
|
||||||
|
|
||||||
pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); /* Get 4 bitplanes / 8 pixels */
|
pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); // Get 4 bitplanes / 8 pixels
|
||||||
if (pack == 0) TileBGM4(cells_dx, pal);
|
if (pack == 0) TileBGM4(cells_dx, pal);
|
||||||
else if (code & 0x0200) TileFlipBGM4(cells_dx, pack, pal);
|
else if (code & 0x0200) TileFlipBGM4(cells_dx, pack, pal);
|
||||||
else TileNormBGM4(cells_dx, pack, pal);
|
else TileNormBGM4(cells_dx, pack, pal);
|
||||||
|
@ -296,17 +301,17 @@ static void DrawDisplayM4(int scanline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Mode 2 */
|
/* TMS Modes */
|
||||||
/*========*/
|
/*===========*/
|
||||||
|
|
||||||
/* Background */
|
/* Background, Graphics modes */
|
||||||
|
|
||||||
#define TMS_PIXELBG(x,p) \
|
#define TMS_PIXELBG(x,p) \
|
||||||
t = (pack>>(7-p)) & 0x01; \
|
t = (pack>>(7-p)) & 0x01; \
|
||||||
t = (pal >> (t << 2)) & 0x0f; \
|
t = (pal >> (t << 2)) & 0x0f; \
|
||||||
pd[x] = t;
|
pd[x] = t;
|
||||||
|
|
||||||
static void TileNormBgM2(u16 sx, unsigned int pack, int pal)
|
static void TileNormBgGr(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
u8 *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
unsigned int t;
|
||||||
|
@ -328,7 +333,7 @@ static void TileNormBgM2(u16 sx, unsigned int pack, int pal)
|
||||||
if (t) \
|
if (t) \
|
||||||
pd[x] = pal;
|
pd[x] = pal;
|
||||||
|
|
||||||
static void TileNormSprM2(u16 sx, unsigned int pack, int pal)
|
static void TileNormSprTMS(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
u8 *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
unsigned int t;
|
||||||
|
@ -343,7 +348,7 @@ static void TileNormSprM2(u16 sx, unsigned int pack, int pal)
|
||||||
TMS_PIXELSP(7, 7)
|
TMS_PIXELSP(7, 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TileDoubleSprM2(u16 sx, unsigned int pack, int pal)
|
static void TileDoubleSprTMS(u16 sx, unsigned int pack, int pal)
|
||||||
{
|
{
|
||||||
u8 *pd = Pico.est.HighCol + sx;
|
u8 *pd = Pico.est.HighCol + sx;
|
||||||
unsigned int t;
|
unsigned int t;
|
||||||
|
@ -367,7 +372,7 @@ static void TileDoubleSprM2(u16 sx, unsigned int pack, int pal)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw sprites into a scanline, max 4 */
|
/* Draw sprites into a scanline, max 4 */
|
||||||
static void DrawSpritesM2(int scanline)
|
static void DrawSpritesTMS(int scanline)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pv = &Pico.video;
|
struct PicoVideo *pv = &Pico.video;
|
||||||
unsigned char mb[256/8+2] = {0};
|
unsigned char mb[256/8+2] = {0};
|
||||||
|
@ -425,14 +430,14 @@ static void DrawSpritesM2(int scanline)
|
||||||
c = sat[MEM_LE2(i+3)] & 0x0f;
|
c = sat[MEM_LE2(i+3)] & 0x0f;
|
||||||
if (x > 0) {
|
if (x > 0) {
|
||||||
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s])];
|
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s])];
|
||||||
if (zoomed) TileDoubleSprM2(x, pack, c);
|
if (zoomed) TileDoubleSprTMS(x, pack, c);
|
||||||
else TileNormSprM2(x, pack, c);
|
else TileNormSprTMS(x, pack, c);
|
||||||
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
||||||
}
|
}
|
||||||
if((pv->reg[1] & 0x2) && (x+=w) > 0) {
|
if((pv->reg[1] & 0x2) && (x+=w) > 0) {
|
||||||
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s]+0x10)];
|
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s]+0x10)];
|
||||||
if (zoomed) TileDoubleSprM2(x, pack, c);
|
if (zoomed) TileDoubleSprTMS(x, pack, c);
|
||||||
else TileNormSprM2(x, pack, c);
|
else TileNormSprTMS(x, pack, c);
|
||||||
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
if (!m) m = CollisionDetect(mb, x, pack, zoomed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,6 +445,9 @@ static void DrawSpritesM2(int scanline)
|
||||||
pv->status |= SR_C;
|
pv->status |= SR_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mode 2 */
|
||||||
|
/*========*/
|
||||||
|
|
||||||
/* Draw the background into a scanline; cells, dx, tilex, ty merged to reduce registers */
|
/* Draw the background into a scanline; cells, dx, tilex, ty merged to reduce registers */
|
||||||
static void DrawStripM2(const u8 *nametab, const u8 *coltab, const u8 *pattab, int cells_dx, int tilex_ty)
|
static void DrawStripM2(const u8 *nametab, const u8 *coltab, const u8 *pattab, int cells_dx, int tilex_ty)
|
||||||
{
|
{
|
||||||
|
@ -452,7 +460,7 @@ static void DrawStripM2(const u8 *nametab, const u8 *coltab, const u8 *pattab, i
|
||||||
code = nametab[tilex_ty & 0x1f] << 3;
|
code = nametab[tilex_ty & 0x1f] << 3;
|
||||||
pal = coltab[code];
|
pal = coltab[code];
|
||||||
pack = pattab[code];
|
pack = pattab[code];
|
||||||
TileNormBgM2(cells_dx, pack, pal);
|
TileNormBgGr(cells_dx, pack, pal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +492,56 @@ static void DrawDisplayM2(int scanline)
|
||||||
|
|
||||||
// sprites
|
// sprites
|
||||||
if (!(pv->debug_p & PVD_KILL_S_LO))
|
if (!(pv->debug_p & PVD_KILL_S_LO))
|
||||||
DrawSpritesM2(scanline);
|
DrawSpritesTMS(scanline);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode 1 */
|
||||||
|
/*========*/
|
||||||
|
|
||||||
|
/* Draw the background into a scanline; cells, dx, tilex, ty merged to reduce registers */
|
||||||
|
static void DrawStripM1(const u8 *nametab, const u8 *coltab, const u8 *pattab, int cells_dx, int tilex_ty)
|
||||||
|
{
|
||||||
|
// Draw tiles across screen:
|
||||||
|
for (; cells_dx > 0; cells_dx += 8, tilex_ty++, cells_dx -= 0x10000)
|
||||||
|
{
|
||||||
|
unsigned int pack, pal;
|
||||||
|
unsigned code;
|
||||||
|
|
||||||
|
code = nametab[tilex_ty & 0x1f];
|
||||||
|
pal = coltab[code >> 3];
|
||||||
|
pack = pattab[code << 3];
|
||||||
|
TileNormBgGr(cells_dx, pack, pal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a scanline */
|
||||||
|
static void DrawDisplayM1(int scanline)
|
||||||
|
{
|
||||||
|
struct PicoVideo *pv = &Pico.video;
|
||||||
|
u8 *nametab, *coltab, *pattab;
|
||||||
|
int tilex, dx, cells;
|
||||||
|
int cellskip = 0; // XXX
|
||||||
|
int maxcells = 32;
|
||||||
|
|
||||||
|
// name, color, pattern table:
|
||||||
|
nametab = PicoMem.vramb + ((pv->reg[2]<<10) & 0x3c00);
|
||||||
|
coltab = PicoMem.vramb + ((pv->reg[3]<< 6) & 0x3fc0);
|
||||||
|
pattab = PicoMem.vramb + ((pv->reg[4]<<11) & 0x3800);
|
||||||
|
|
||||||
|
nametab += (scanline>>3) << 5;
|
||||||
|
pattab += (scanline & 0x7);
|
||||||
|
|
||||||
|
tilex = cellskip & 0x1f;
|
||||||
|
cells = maxcells - cellskip;
|
||||||
|
dx = (cellskip << 3) + line_offset + 8;
|
||||||
|
|
||||||
|
// tiles
|
||||||
|
if (!(pv->debug_p & PVD_KILL_B))
|
||||||
|
DrawStripM1(nametab, coltab, pattab, dx | (cells << 16), tilex | (scanline << 16));
|
||||||
|
|
||||||
|
// sprites
|
||||||
|
if (!(pv->debug_p & PVD_KILL_S_LO))
|
||||||
|
DrawSpritesTMS(scanline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -569,7 +626,8 @@ void PicoLineSMS(int line)
|
||||||
BackFill(Pico.video.reg[7] & 0x0f, 0, &Pico.est);
|
BackFill(Pico.video.reg[7] & 0x0f, 0, &Pico.est);
|
||||||
if (Pico.video.reg[1] & 0x40) {
|
if (Pico.video.reg[1] & 0x40) {
|
||||||
if (Pico.video.reg[0] & 0x04) DrawDisplayM4(line);
|
if (Pico.video.reg[0] & 0x04) DrawDisplayM4(line);
|
||||||
else DrawDisplayM2(line);
|
else if (Pico.video.reg[0] & 0x02) DrawDisplayM2(line);
|
||||||
|
else DrawDisplayM1(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FinalizeLineSMS != NULL)
|
if (FinalizeLineSMS != NULL)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue