summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatarGravatar r09 <rzero9@gmail.com>2017-12-13 11:07:49 +0100
committerGravatarGravatar Vas Crabb <cuavas@users.noreply.github.com>2017-12-13 21:07:49 +1100
commit3334442d5b2cbd862b503e16854a4c8a8dfb5cdb (patch) (github)
treea21cd33b54814d14c36860a8c24239ed96d74517
parentb6ca334e31c8406624fecb936cb044eed5ac1e90 (diff)
downloadmame-3334442d5b2cbd862b503e16854a4c8a8dfb5cdb.tar.bz2
mame-3334442d5b2cbd862b503e16854a4c8a8dfb5cdb.zip
fmtowns: implement half-size mode for sprites (#2921)
-rw-r--r--src/mame/includes/fmtowns.h4
-rw-r--r--src/mame/video/fmtowns.cpp115
2 files changed, 87 insertions, 32 deletions
diff --git a/src/mame/includes/fmtowns.h b/src/mame/includes/fmtowns.h
index ea04463de5f..210e0cd8ebe 100644
--- a/src/mame/includes/fmtowns.h
+++ b/src/mame/includes/fmtowns.h
@@ -372,8 +372,8 @@ public:
void towns_crtc_refresh_mode();
void towns_update_kanji_offset();
void towns_update_palette();
- void render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x, uint16_t y, uint16_t xflip, uint16_t yflip, const rectangle* rect);
- void render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, uint16_t xflip, uint16_t yflip, const rectangle* rect);
+ void render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x, uint16_t y, bool xflip, bool yflip, bool xhalfsize, bool yhalfsize, const rectangle* rect);
+ void render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, bool xflip, bool yflip, bool xhalfsize, bool yhalfsize, const rectangle* rect);
void draw_sprites(const rectangle* rect);
void towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const rectangle* rect,int layer,int line,int scanline);
void towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rectangle* rect,int layer,int line,int scanline);
diff --git a/src/mame/video/fmtowns.cpp b/src/mame/video/fmtowns.cpp
index d9badf4c7d5..828614a34e7 100644
--- a/src/mame/video/fmtowns.cpp
+++ b/src/mame/video/fmtowns.cpp
@@ -709,13 +709,13 @@ WRITE8_MEMBER( towns_state::towns_spriteram_w )
* +2: Y position (10-bit)
* +4: Sprite Attribute
* bit 15: enforce offsets (regs 2-5)
- * bit 12,13: flip sprite
- * bits 10-0: Sprite RAM offset containing sprite pattern
- * TODO: other attributes (zoom?)
+ * bit 12,13,14: flip / rotate sprite
+ * bits 10,11: half-size
+ * bits 9-0: Sprite RAM offset containing sprite pattern
* +6: Sprite Colour
* bit 15: use colour data in located in sprite RAM offset in bits 11-0 (x32)
*/
-void towns_state::render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x, uint16_t y, uint16_t xflip, uint16_t yflip, const rectangle* rect)
+void towns_state::render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x, uint16_t y, bool xflip, bool yflip, bool xhalfsize, bool yhalfsize, const rectangle* rect)
{
uint16_t xpos,ypos;
uint16_t col,pixel;
@@ -728,25 +728,47 @@ void towns_state::render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x
if(xflip)
{
xstart = x+14;
- xend = x-2;
- xdir = -2;
+ if (xhalfsize)
+ {
+ xend = x+6;
+ xdir = -1;
+ }
+ else
+ {
+ xend = x-2;
+ xdir = -2;
+ }
}
else
{
xstart = x+1;
- xend = x+17;
- xdir = 2;
+ if (xhalfsize)
+ {
+ xend = x+9;
+ xdir = 1;
+ }
+ else
+ {
+ xend = x+17;
+ xdir = 2;
+ }
}
if(yflip)
{
ystart = y+15;
- yend = y-1;
+ if (yhalfsize)
+ yend = y+7;
+ else
+ yend = y-1;
ydir = -1;
}
else
{
ystart = y;
- yend = y+16;
+ if (yhalfsize)
+ yend = y+8;
+ else
+ yend = y+16;
ydir = 1;
}
xstart &= 0x1ff;
@@ -754,7 +776,7 @@ void towns_state::render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x
ystart &= 0x1ff;
yend &= 0x1ff;
poffset &= 0x1ffff;
-
+
for(ypos=ystart;ypos!=yend;ypos+=ydir,ypos&=0x1ff)
{
for(xpos=xstart;xpos!=xend;xpos+=xdir,xpos&=0x1ff)
@@ -776,28 +798,37 @@ void towns_state::render_sprite_4(uint32_t poffset, uint32_t coffset, uint16_t x
m_towns_gfxvram[0x40000+voffset] = col & 0x00ff;
}
}
- if(xflip)
- voffset+=2;
- else
- voffset-=2;
- pixel = m_towns_txtvram[poffset] & 0x0f;
- col = m_towns_txtvram[coffset+(pixel*2)] | (m_towns_txtvram[coffset+(pixel*2)+1] << 8);
- if((m_video.towns_sprite_page != 0 && voffset > 0x1ffff && voffset < 0x40000)
- || (m_video.towns_sprite_page == 0 && voffset < 0x20000))
+
+ if (!xhalfsize)
{
- if(xpos < width && ypos < height && pixel != 0)
+ if(xflip)
+ voffset+=2;
+ else
+ voffset-=2;
+ pixel = m_towns_txtvram[poffset] & 0x0f;
+ col = m_towns_txtvram[coffset+(pixel*2)] | (m_towns_txtvram[coffset+(pixel*2)+1] << 8);
+ if((m_video.towns_sprite_page != 0 && voffset > 0x1ffff && voffset < 0x40000)
+ || (m_video.towns_sprite_page == 0 && voffset < 0x20000))
{
- m_towns_gfxvram[0x40000+voffset+1] = (col & 0xff00) >> 8;
- m_towns_gfxvram[0x40000+voffset] = col & 0x00ff;
+ if(xpos < width && ypos < height && pixel != 0)
+ {
+ m_towns_gfxvram[0x40000+voffset+1] = (col & 0xff00) >> 8;
+ m_towns_gfxvram[0x40000+voffset] = col & 0x00ff;
+ }
}
}
+
poffset++;
poffset &= 0x1ffff;
}
+ if (yhalfsize)
+ {
+ poffset+=8;
+ }
}
}
-void towns_state::render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, uint16_t xflip, uint16_t yflip, const rectangle* rect)
+void towns_state::render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, bool xflip, bool yflip, bool xhalfsize, bool yhalfsize, const rectangle* rect)
{
uint16_t xpos,ypos;
uint16_t col;
@@ -810,25 +841,37 @@ void towns_state::render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, uin
if(xflip)
{
xstart = x+16;
- xend = x;
+ if (xhalfsize)
+ xend = x+8;
+ else
+ xend = x;
xdir = -1;
}
else
{
xstart = x+1;
- xend = x+17;
+ if (xhalfsize)
+ xend = x+9;
+ else
+ xend = x+17;
xdir = 1;
}
if(yflip)
{
ystart = y+15;
- yend = y-1;
+ if (yhalfsize)
+ yend = y+7;
+ else
+ yend = y-1;
ydir = -1;
}
else
{
ystart = y;
- yend = y+16;
+ if (yhalfsize)
+ yend = y+16;
+ else
+ yend = y+8;
ydir = 1;
}
xstart &= 0x1ff;
@@ -857,9 +900,15 @@ void towns_state::render_sprite_16(uint32_t poffset, uint16_t x, uint16_t y, uin
m_towns_gfxvram[0x40000+voffset] = col & 0x00ff;
}
}
- poffset+=2;
+ if (xhalfsize)
+ poffset+=4;
+ else
+ poffset+=2;
poffset &= 0x1ffff;
}
+
+ if (yhalfsize)
+ poffset+=16;
}
}
@@ -871,6 +920,7 @@ void towns_state::draw_sprites(const rectangle* rect)
uint16_t xoff = (m_video.towns_sprite_reg[2] | (m_video.towns_sprite_reg[3] << 8)) & 0x1ff;
uint16_t yoff = (m_video.towns_sprite_reg[4] | (m_video.towns_sprite_reg[5] << 8)) & 0x1ff;
uint32_t poffset,coffset;
+ bool xflip, yflip, xhalfsize, yhalfsize;
if(!(m_video.towns_sprite_reg[1] & 0x80))
return;
@@ -887,6 +937,11 @@ void towns_state::draw_sprites(const rectangle* rect)
y = m_towns_txtvram[8*n+2] | (m_towns_txtvram[8*n+3] << 8);
attr = m_towns_txtvram[8*n+4] | (m_towns_txtvram[8*n+5] << 8);
colour = m_towns_txtvram[8*n+6] | (m_towns_txtvram[8*n+7] << 8);
+ xflip = (attr & 0x2000) >> 13;
+ yflip = (attr & 0x1000) >> 12;
+ xhalfsize = (attr & 0x400) >> 10;
+ yhalfsize = (attr & 0x800) >> 11;
+
if(attr & 0x8000)
{
x += xoff;
@@ -904,7 +959,7 @@ void towns_state::draw_sprites(const rectangle* rect)
n,x,y,attr,colour,poffset,coffset);
#endif
if(!(colour & 0x2000))
- render_sprite_4((poffset)&0x1ffff,coffset,x,y,attr&0x2000,attr&0x1000,rect);
+ render_sprite_4((poffset)&0x1ffff,coffset,x,y,xflip,yflip,xhalfsize,yhalfsize,rect);
}
else
{
@@ -914,7 +969,7 @@ void towns_state::draw_sprites(const rectangle* rect)
n,x,y,attr,colour,poffset);
#endif
if(!(colour & 0x2000))
- render_sprite_16((poffset)&0x1ffff,x,y,attr&0x2000,attr&0x1000,rect);
+ render_sprite_16((poffset)&0x1ffff,x,y,xflip,yflip,xhalfsize,yhalfsize,rect);
}
}