diff options
Diffstat (limited to 'src/mame/video/ms32.cpp')
-rw-r--r-- | src/mame/video/ms32.cpp | 218 |
1 files changed, 110 insertions, 108 deletions
diff --git a/src/mame/video/ms32.cpp b/src/mame/video/ms32.cpp index c7addf9bb0a..19e4dbda41a 100644 --- a/src/mame/video/ms32.cpp +++ b/src/mame/video/ms32.cpp @@ -18,8 +18,6 @@ priority should be given to #include "includes/ms32.h" -// kirarast, tp2m32, and suchie2 require the sprites in a different order - /********** Tilemaps **********/ TILE_GET_INFO_MEMBER(ms32_state::get_ms32_tx_tile_info) @@ -52,12 +50,12 @@ TILE_GET_INFO_MEMBER(ms32_state::get_ms32_bg_tile_info) tileinfo.set(1,tileno,colour,0); } -TILE_GET_INFO_MEMBER(ms32_state::get_ms32_extra_tile_info) +TILE_GET_INFO_MEMBER(ms32_f1superbattle_state::get_ms32_extra_tile_info) { int tileno,colour; - tileno = m_f1superb_extraram[tile_index *2] & 0xffff; - colour = m_f1superb_extraram[tile_index *2+1] & 0x000f; + tileno = m_road_vram[tile_index *2] & 0xffff; + colour = m_road_vram[tile_index *2+1] & 0x000f; tileinfo.set(3,tileno,colour+0x50,0); } @@ -68,11 +66,12 @@ void ms32_state::video_start() { m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_bg_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 64, 64); - m_bg_tilemap_alt = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_bg_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 256, 16); // alt layout, controller by register? + // alt layout, controller by register + m_bg_tilemap_alt = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_bg_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 256, 16); m_roz_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_roz_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 128,128); - size_t size = m_sprram.bytes() / 4; - m_sprram_buffer = make_unique_clear<u16[]>(size); + m_objectram_size = m_sprram.length(); + m_sprram_buffer = make_unique_clear<u16[]>(m_objectram_size); /* set up tile layers */ m_screen->register_screen_bitmap(m_temp_bitmap_tilemaps); @@ -88,64 +87,63 @@ void ms32_state::video_start() m_bg_tilemap_alt->set_transparent_pen(0); m_roz_tilemap->set_transparent_pen(0); - m_reverse_sprite_order = 1; - - /* i hate per game patches...how should priority really work? tetrisp2.c ? i can't follow it */ - if (!strcmp(machine().system().name,"kirarast")) m_reverse_sprite_order = 0; - if (!strcmp(machine().system().name,"tp2m32")) m_reverse_sprite_order = 0; - if (!strcmp(machine().system().name,"suchie2")) m_reverse_sprite_order = 0; - if (!strcmp(machine().system().name,"suchie2o")) m_reverse_sprite_order = 0; - if (!strcmp(machine().system().name,"hayaosi3")) m_reverse_sprite_order = 0; - if (!strcmp(machine().system().name,"bnstars")) m_reverse_sprite_order = 0; - if (!strcmp(machine().system().name,"wpksocv2")) m_reverse_sprite_order = 0; - // tp2m32 doesn't set the brightness registers so we need sensible defaults m_brt[0] = m_brt[1] = 0xffff; + m_sprite_ctrl[0x10/4] = 0x8000; - save_pointer(NAME(m_sprram_buffer), size); - save_item(NAME(m_irqreq)); + save_pointer(NAME(m_sprram_buffer), m_objectram_size); save_item(NAME(m_temp_bitmap_tilemaps)); save_item(NAME(m_temp_bitmap_sprites)); save_item(NAME(m_temp_bitmap_sprites_pri)); save_item(NAME(m_tilemaplayoutcontrol)); - save_item(NAME(m_reverse_sprite_order)); - save_item(NAME(m_flipscreen)); save_item(NAME(m_brt)); save_item(NAME(m_brt_r)); save_item(NAME(m_brt_g)); save_item(NAME(m_brt_b)); } -VIDEO_START_MEMBER(ms32_state,f1superb) +void ms32_f1superbattle_state::video_start() { ms32_state::video_start(); - m_extra_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_extra_tile_info)), TILEMAP_SCAN_ROWS, 2048, 1, 1, 0x400); + m_extra_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_f1superbattle_state::get_ms32_extra_tile_info)), TILEMAP_SCAN_ROWS, 2048, 1, 1, 0x400); } /********** PALETTE WRITES **********/ +// TODO: fix p47aces brightness +// intro text should actually appear one line at a time instead of fading-in altogether, +// see https://youtu.be/PQsefFtqAwA void ms32_state::update_color(int color) { + // anything above text layer is unaffected (maybe a priority setting?) + // that means this must happen at mixing time rather than here ... + // bnstars gameplay: 0x0000 0x0000 0x8080 0x0080 + // desertwr ranking: 0x8080 0xff80 0x0000 0x0000 + // gametngk: sets upper words of first two regs as 0x0100xxxx (discarded?) + // gameplay:0x0000 0x0000 0x2020 0x0020 + // continue:0x5050 0x0050 0x2020 0x0020 + // hayaosi3 title: 0x7070 0x0070 0x0000 0x0000 + // p47aces: bomb on stage clear fade out (untested, tbd) + int r,g,b; /* I'm not sure how the brightness should be applied, currently I'm only affecting bg & sprites, not fg. The second brightness control might apply to shadows, see gametngk. */ - // TODO : p47aces : brightness are disabled sometimes, see https://youtu.be/PQsefFtqAwA if (~color & 0x4000) { - r = ((m_palram[color*2] & 0xff00) >>8 ) * m_brt_r / 0x100; - g = ((m_palram[color*2] & 0x00ff) >>0 ) * m_brt_g / 0x100; - b = ((m_palram[color*2+1] & 0x00ff) >>0 ) * m_brt_b / 0x100; + r = ((m_palram[color*2] & 0xff00) >> 8 ) * m_brt_r / 0x100; + g = ((m_palram[color*2] & 0x00ff) >> 0 ) * m_brt_g / 0x100; + b = ((m_palram[color*2+1] & 0x00ff) >> 0 ) * m_brt_b / 0x100; } else { - r = ((m_palram[color*2] & 0xff00) >>8 ); - g = ((m_palram[color*2] & 0x00ff) >>0 ); - b = ((m_palram[color*2+1] & 0x00ff) >>0 ); + r = ((m_palram[color*2] & 0xff00) >> 8 ); + g = ((m_palram[color*2] & 0x00ff) >> 0 ); + b = ((m_palram[color*2+1] & 0x00ff) >> 0 ); } m_palette->set_pen_color(color,rgb_t(r,g,b)); @@ -156,8 +154,10 @@ void ms32_state::ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask) int oldword = m_brt[offset]; COMBINE_DATA(&m_brt[offset]); + if (m_brt[offset] != oldword) { + // TODO: bank "1" is for sprite colors int bank = ((offset & 2) >> 1) * 0x4000; //int i; @@ -171,45 +171,23 @@ void ms32_state::ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask) // update_color(machine(), i); } } - -//popmessage("%04x %04x %04x %04x",m_brt[0],m_brt[1],m_brt[2],m_brt[3]); -} - - - - - - -void ms32_state::ms32_gfxctrl_w(offs_t offset, u32 data, u32 mem_mask) -{ - if (ACCESSING_BITS_0_7) - { - /* bit 1 = flip screen */ - m_flipscreen = data & 0x02; - m_tx_tilemap->set_flip(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); - m_bg_tilemap->set_flip(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); - m_bg_tilemap_alt->set_flip(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); - - /* bit 2 used by f1superb, unknown */ - - /* bit 3 used by several games, unknown */ - -//popmessage("%08x",data); - } } - /* SPRITES based on tetrisp2 for now, readd priority bits later */ -void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u16 *sprram_top, size_t sprram_size, int reverseorder) +void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u16 *sprram_top) { - u16 *source = sprram_top; - u16 *finish = sprram_top + (sprram_size - 0x10) / 2; - - if (reverseorder == 1) + const size_t sprite_tail = m_objectram_size - 8; //(0x20000 - 0x10) / 2; + u16 *source = sprram_top; + u16 *finish = sprram_top + sprite_tail; + // TODO: sprite control 0x10 also uses bits 0-11 for sprite start address? + // akiss uses it for double buffer animations, flips between 0 and 0x800 (and is ugly for latter) + const bool reverseorder = (m_sprite_ctrl[0x10/4] & 0x8000) == 0x0000; + + if (reverseorder == true) { - source = sprram_top + (sprram_size - 0x10) / 2; - finish = sprram_top; + source = sprram_top + sprite_tail; + finish = sprram_top; } for (;reverseorder ? (source>=finish) : (source<finish); reverseorder ? (source-=8) : (source+=8)) @@ -222,8 +200,8 @@ void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, con u16 xsize, ysize; s32 sx, sy; u16 xzoom, yzoom; - - m_sprite->extract_parameters(true, false, source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom); + + m_sprite->extract_parameters(source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom); if (disable || !xzoom || !yzoom) continue; @@ -244,20 +222,21 @@ void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, con void ms32_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect,int priority) { // TODO: registers 0x40 / 0x44 and 0x50 / 0x54 are used, unknown meaning - // Given how this works out it is most likely that 0x*0 controls X axis while 0x*4 Y, - // nothing is known to diverge between settings so far (i.e. bbbxing sets 0xffff to 0x4* and 0x0000 to 0x5*). - // 0x4* 0x5* ROZ should wrap? - // bbbxing: 0xffff 0x0000 0 (match presentation) - // gratia: 0x0000 0x0000 1 (sky in stage 2) - // p47aces: 0xffff 0x0651 0 (title screen) - // desertwr: 0xffff 0x0651 1 (any stage) - // f1superb: 0xffff 0x0000 ? - // suchie2: 0x0000 0x0000 0? - // bnstars: 0x0000 0x0000 ? - // hayaosi3: 0x0000 0x0000 ? - // Maybe wrapping is done by limit boundaries rather than individual bits, so that bbbxing and p47aces abuses of this behaviour? - // Are we missing a ROZ plane size as well? - + // Given how this works out it is most likely that 0x*0 controls X axis while 0x*4 Y, + // nothing is known to diverge between settings so far (i.e. bbbxing sets 0xffff to 0x4* and 0x0000 to 0x5*). + // 0x4* 0x5* ROZ should wrap? + // bbbxing: 0xffff 0x0000 0 (match presentation) + // gratia: 0x0000 0x0000 1 (sky in stage 2) + // p47aces: 0xffff 0x0651 0 (title screen) + // desertwr: 0xffff 0x0651 1 (any stage) + // f1superb: 0xffff 0x0000 ? + // suchie2: 0x0000 0x0000 0? + // bnstars: 0x0000 0x0000 ? + // hayaosi3: 0x0000 0x0000 ? + // akiss: 0xffff 0x0000 0 (gal riichi, cfr. attract mode) + // Maybe wrapping is done by limit boundaries rather than individual bits, so that bbbxing and p47aces abuses of this behaviour? + // Are we missing a ROZ plane size as well? + if (m_roz_ctrl[0x5c/4] & 1) /* "super" mode */ { rectangle my_clip; @@ -336,13 +315,36 @@ void ms32_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rec -u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +u32 ms32_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { int scrollx,scrolly; int asc_pri; int scr_pri; int rot_pri; + /* + sprite control regs + 0x1c 0x20 0x40 <prihack> + akiss 0 0 0 0 + bbbxing 0 0 0 0 + bnstars 1 0 0 1 + bnstars1 ? ? ? 1 + desertwr 1 0 0 0 + f1superb 0 0 0 0 + gametngk 0 0140 0 0 + gratia 0 0 0 0 + hayaosi2 0 0 0 0 + hayaosi3 0 0140 0 1 + kirarast 0 0 0 1 + p47aces 1 0 0 0 + suchie2 0 0 0 1 + tetrisp 0 0 0 0 + tp2m32 0 0140 0 1 + wpksocv2 0 0140 0 1 + */ +// popmessage("%04x %04x %04x",m_sprite_ctrl[0x1c/4], m_sprite_ctrl[0x20/4], m_sprite_ctrl[0x40/4]); +// popmessage("%04x %04x %04x %04x|%04x %04x %04x",m_sprite_ctrl[0x00/4],m_sprite_ctrl[0x04/4],m_sprite_ctrl[0x08/4],m_sprite_ctrl[0x0c/4] +// ,m_sprite_ctrl[0x10/4],m_sprite_ctrl[0x14/4],m_sprite_ctrl[0x18/4]); /* TODO: registers 0x04/4 and 0x10/4 are used too; the most interesting case is gametngk, where they are *usually*, but not always, copies of 0x00/4 and 0x0c/4 (used for scrolling). @@ -351,9 +353,9 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, The two registers might be somewhat related to the width and height of the tilemaps, but there's something that just doesn't fit. */ - int i; - for (i = 0;i < 0x10000;i++) // colors 0x3000-0x3fff are not used + // TODO: move to a cache system + for (int i = 0; i < m_palette->entries(); i++) // colors 0x3000-0x3fff are not used update_color(i); scrollx = m_tx_scroll[0x00/4] + m_tx_scroll[0x08/4] + 0x18; @@ -368,11 +370,8 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, m_bg_tilemap_alt->set_scrollx(0, scrollx); m_bg_tilemap_alt->set_scrolly(0, scrolly); - screen.priority().fill(0, cliprect); - - /* TODO: 0 is correct for gametngk, but break f1superb scrolling grid (text at top and bottom of the screen becomes black on black) */ m_temp_bitmap_tilemaps.fill(0, cliprect); /* bg color */ @@ -381,8 +380,7 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, m_temp_bitmap_sprites.fill(0, cliprect); m_temp_bitmap_sprites_pri.fill(0, cliprect); - draw_sprites(m_temp_bitmap_sprites, m_temp_bitmap_sprites_pri, cliprect, m_sprram_buffer.get(), 0x20000, m_reverse_sprite_order); - + draw_sprites(m_temp_bitmap_sprites, m_temp_bitmap_sprites_pri, cliprect, m_sprram_buffer.get()); // TODO: actually understand this (per-scanline priority and alpha-blend over every layer?) asc_pri = scr_pri = rot_pri = 0; @@ -431,31 +429,32 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, } // tile-sprite mixing - /* this mixing isn't 100% accurate, it should be using ALL the data in - the priority ram, probably for per-pixel / pen mixing, or more levels - than are supported here.. I don't know, it will need hw tests I think */ + // TODO: spaghetti code + // TODO: complete guesswork and missing many spots + // TODO: move to a reusable function + /* it should be using ALL the data in the priority ram, probably for + per-pixel / pen mixing, or more levels than are supported here.. + I don't know, it will need hw tests I think */ { - int width = screen.width(); - int height = screen.height(); pen_t const *const paldata = m_palette->pens(); - bitmap.fill(0, cliprect); - - for (int yy=0;yy<height;yy++) + + for (int yy = cliprect.min_y; yy <= cliprect.max_y; yy++) { u16 const *const srcptr_tile = &m_temp_bitmap_tilemaps.pix(yy); u8 const *const srcptr_tilepri = &screen.priority().pix(yy); u16 const *const srcptr_spri = &m_temp_bitmap_sprites.pix(yy); //u8 const *const srcptr_spripri = &m_temp_bitmap_sprites_pri.pix(yy); u32 *const dstptr_bitmap = &bitmap.pix(yy); - for (int xx=0;xx<width;xx++) + + for (int xx = cliprect.min_x; xx <= cliprect.max_x; xx++) { u16 src_tile = srcptr_tile[xx]; u8 src_tilepri = srcptr_tilepri[xx]; u16 src_spri = srcptr_spri[xx]; //u8 src_spripri;// = srcptr_spripri[xx]; - u16 spridat = ((src_spri&0x0fff)); - u8 spritepri = ((src_spri&0xf000) >> 8); + u16 spridat = (src_spri & 0x0fff); + u8 spritepri = ((src_spri & 0xf000) >> 8); int primask = 0; // get sprite priority value back out of bitmap/colour data (this is done in draw_sprite for standalone hw) @@ -468,7 +467,6 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, if (m_priram[(spritepri | 0x0a00 | 0x0100) / 2] & 0x38) primask |= 1 << 6; if (m_priram[(spritepri | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7; - // TODO: spaghetti code ... if (primask == 0x00) { if (src_tilepri==0x00) @@ -691,22 +689,26 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, dstptr_bitmap[xx] = 0; popmessage("unhandled priority type %02x, contact MAMEdev",primask); } - - - } - } - } return 0; } -WRITE_LINE_MEMBER(ms32_state::screen_vblank_ms32) +WRITE_LINE_MEMBER(ms32_state::screen_vblank) { if (state) { - std::copy_n(&m_sprram[0], m_sprram.bytes() / 4, &m_sprram_buffer[0]); + std::copy_n(&m_sprram[0], m_objectram_size, &m_sprram_buffer[0]); } } + +WRITE_LINE_MEMBER(ms32_state::flipscreen_w) +{ + m_tx_tilemap->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + m_bg_tilemap->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + m_bg_tilemap_alt->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + m_roz_tilemap->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); + // TODO: sprite device +} |