From 6bfac6709c70a4024cffd643069f33b3f39e8a22 Mon Sep 17 00:00:00 2001 From: angelosa Date: Thu, 3 Oct 2024 19:01:38 +0200 Subject: jaleco/acommand.cpp: port over cischeat_draw_sprites --- src/mame/jaleco/acommand.cpp | 168 +++++++++++++++++++++++++++++-------------- 1 file changed, 113 insertions(+), 55 deletions(-) diff --git a/src/mame/jaleco/acommand.cpp b/src/mame/jaleco/acommand.cpp index 7cc8dd9ed37..ec06efcb249 100644 --- a/src/mame/jaleco/acommand.cpp +++ b/src/mame/jaleco/acommand.cpp @@ -102,11 +102,14 @@ private: void ext_devices_1_w(uint16_t data); void ext_devices_2_w(uint16_t data); + uint8_t m_drawmode_table[16]{}; + void draw_sprites(bitmap_ind16 &bitmap , const rectangle &cliprect, int priority1, int priority2); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb); void main_map(address_map &map) ATTR_COLD; + virtual void video_start() override ATTR_COLD; virtual void machine_start() override ATTR_COLD; required_device m_maincpu; @@ -122,8 +125,6 @@ private: uint16_t m_7seg1 = 0; uint16_t m_ufo_lane[5]{}; uint8_t m_boss_door = 0; - - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority, int pri_mask); }; void acommand_state::machine_start() @@ -131,75 +132,132 @@ void acommand_state::machine_start() m_digits.resolve(); } -void acommand_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority, int pri_mask) +// TODO: copied over from cischeat_draw_sprites, merge in common device +void acommand_state::video_start() { - uint16_t *spriteram16 = m_spriteram; - int offs; + for (int i = 0; i < 16; i++) + m_drawmode_table[i] = DRAWMODE_SOURCE; + + m_drawmode_table[ 0] = DRAWMODE_SHADOW; + m_drawmode_table[15] = DRAWMODE_NONE; +} + +#define SHRINK(_org_,_fact_) ( ( ( (_org_) << 16 ) * (_fact_ & 0x01ff) ) / 0x80 ) + +void acommand_state::draw_sprites(bitmap_ind16 &bitmap , const rectangle &cliprect, int priority1, int priority2) +{ + int x, sx, flipx, xzoom, xscale, xdim, xnum, xstart, xend, xinc; + int y, sy, flipy, yzoom, yscale, ydim, ynum, ystart, yend, yinc; + int code, attr, color, size, shadow; + + int min_priority, max_priority, high_sprites; - for (offs = 0;offs < m_spriteram.bytes()/2;offs += 8) + uint16_t *source = m_spriteram; + const uint16_t *finish = source + 0x1000/2; + + /* Move the priority values in place */ + high_sprites = (priority1 >= 16) | (priority2 >= 16); + priority1 = (priority1 & 0x0f) * 0x100; + priority2 = (priority2 & 0x0f) * 0x100; + + if (priority1 < priority2) { min_priority = priority1; max_priority = priority2; } + else { min_priority = priority2; max_priority = priority1; } + + for (; source < finish; source += 0x10/2 ) { - if (!(spriteram16[offs+0] & 0x1000)) + size = source[ 0 ]; + if (size & 0x1000) continue; + + /* number of tiles */ + xnum = ( (size & 0x0f) >> 0 ) + 1; + ynum = ( (size & 0xf0) >> 4 ) + 1; + + xzoom = source[ 1 ]; + yzoom = source[ 2 ]; + flipx = xzoom & 0x1000; + flipy = yzoom & 0x1000; + + sx = source[ 3 ]; + sy = source[ 4 ]; + // TODO: was & 0x1ff with 0x200 as sprite wrap sign, looks incorrect with Grand Prix Star + // during big car on side view in attract mode (a tyre gets stuck on the right of the screen) + // this arrangement works with both games (otherwise Part 2 gets misaligned bleachers sprites) + sx = (sx & 0x7ff); + sy = (sy & 0x7ff); + if(sx & 0x400) + sx -= 0x800; + if(sy & 0x400) + sy -= 0x800; + + /* use fixed point values (16.16), for accuracy */ + sx <<= 16; + sy <<= 16; + + /* dimension of a tile after zoom */ { - int sx = (spriteram16[offs+3] & 0x0ff); - int code = spriteram16[offs+6]; - int color = spriteram16[offs+7]; - int w = (spriteram16[offs+0] & 0x0f); - int h = ((spriteram16[offs+0] & 0xf0) >> 4); - int sy = (spriteram16[offs+4] & 0x0ff) - ((h+1)*0x10); -/**/ int pri = spriteram16[offs+5]; -/**/ int flipy = ((spriteram16[offs+1] & 0x2000) >> 13); - // "this is the boss" uses flip x - int flipx = ((spriteram16[offs+1] & 0x1000) >> 12); - - int xx,yy,x; - int delta = 16; - - flipx ^= flip_screen(); - flipy ^= flip_screen(); - - if ((pri&pri_mask)!=priority) continue; - - if (flip_screen()) - { - sx = 368 - sx; - sy = 240 - sy; - delta = -16; - } + xdim = SHRINK(16,xzoom); + ydim = SHRINK(16,yzoom); + } + + if ( ( (xdim / 0x10000) == 0 ) || ( (ydim / 0x10000) == 0) ) continue; - yy = h; - do + /* the y pos passed to the hardware is the that of the last line, + we need the y pos of the first line */ + sy -= (ydim * ynum); + + code = source[ 6 ]; + attr = source[ 7 ]; + color = attr & 0x007f; + shadow = attr & 0x1000; + + /* high byte is a priority information */ + if ( ((attr & 0x700) < min_priority) || ((attr & 0x700) > max_priority) ) + continue; + + if ( high_sprites && !(color & 0x80) ) + continue; + + xscale = xdim / 16; + yscale = ydim / 16; + + + /* let's approximate to the nearest greater integer value + to avoid holes in between tiles */ + if (xscale & 0xffff) xscale += (1<<16)/16; + if (yscale & 0xffff) yscale += (1<<16)/16; + + + if (flipx) { xstart = xnum-1; xend = -1; xinc = -1; } + else { xstart = 0; xend = xnum; xinc = +1; } + + if (flipy) { ystart = ynum-1; yend = -1; yinc = -1; } + else { ystart = 0; yend = ynum; yinc = +1; } + + m_drawmode_table[ 0] = shadow ? DRAWMODE_SHADOW : DRAWMODE_SOURCE; + + for (y = ystart; y != yend; y += yinc) + { + for (x = xstart; x != xend; x += xinc) { - x = flipx ? sx + w*16 : sx; - xx = w; - do - { - m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, - code, - color, - flipx, flipy, - ((x + 16) & 0x1ff) - 16,sy & 0x1ff,15); - - code++; - if(flipx) - x -= delta; - else - x += delta; - } while (--xx >= 0); - - sy += delta; - } while (--yy >= 0); + m_gfxdecode->gfx(0)->zoom_transtable(bitmap,cliprect,code++,color,flipx,flipy, + (sx + x * xdim) / 0x10000, (sy + y * ydim) / 0x10000, + xscale, yscale, m_drawmode_table); + } } } } - uint32_t acommand_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // reference has black pen background, as weird it might sound bitmap.fill(m_palette->black_pen(), cliprect); m_bgtmap->draw(screen, bitmap, cliprect, 0, 0); - draw_sprites(bitmap,cliprect,0,0); + // TODO: isn't this supposed to use pdrawgfx? + draw_sprites(bitmap,cliprect,15,3); + draw_sprites(bitmap,cliprect,2,2); + draw_sprites(bitmap,cliprect,1,0); + draw_sprites(bitmap,cliprect,0+16,0+16); m_txtmap->draw(screen, bitmap, cliprect, 0, 0); return 0; -- cgit v1.2.3