summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/raiden2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/raiden2.cpp')
-rw-r--r--src/mame/video/raiden2.cpp385
1 files changed, 385 insertions, 0 deletions
diff --git a/src/mame/video/raiden2.cpp b/src/mame/video/raiden2.cpp
new file mode 100644
index 00000000000..5679c15a296
--- /dev/null
+++ b/src/mame/video/raiden2.cpp
@@ -0,0 +1,385 @@
+// license:LGPL-2.1+
+// copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina
+/********************************************************************************************************
+
+ Seibu Protected 1993-94 era hardware, V30 based (sequel to the SYS68C hardware)
+
+********************************************************************************************************/
+
+#include "emu.h"
+#include "includes/raiden2.h"
+
+WRITE16_MEMBER(raiden2_state::m_videoram_private_w)
+{
+ // map(0x0d000, 0x0d7ff).ram().w(FUNC(raiden2_state::background_w)).share("back_data");
+ // map(0x0d800, 0x0dfff).ram().w(FUNC(raiden2_state::foreground_w).share("fore_data");
+ // map(0x0e000, 0x0e7ff).ram().w(FUNC(raiden2_state::midground_w).share("mid_data");
+ // map(0x0e800, 0x0f7ff).ram().w(FUNC(raiden2_state::text_w).share("text_data");
+
+ if (offset < 0x800 / 2)
+ {
+ background_w(space, offset, data, 0xffff);
+ }
+ else if (offset < 0x1000 /2)
+ {
+ offset -= 0x800 / 2;
+ foreground_w(space, offset, data, 0xffff);
+ }
+ else if (offset < 0x1800/2)
+ {
+ offset -= 0x1000 / 2;
+ midground_w(space, offset, data, 0xffff);
+ }
+ else if (offset < 0x2800/2)
+ {
+ offset -= 0x1800 / 2;
+ text_w(space, offset, data, 0xffff);
+ }
+}
+
+
+void raiden2_state::draw_sprites(const rectangle &cliprect)
+{
+ uint16_t *source = m_spriteram + (0x1000/2)-4;
+ m_sprite_bitmap.fill(0xf, cliprect);
+
+ gfx_element *gfx = m_gfxdecode->gfx(2);
+
+ /*
+ 00 fhhh Fwww ppcc cccc h = height f=flipy w = width F = flipx p = priority c = color
+ 02 nnnn nnnn nnnn nnnn n = tileno
+ 04 xxxx xxxx xxxx xxxx x = xpos
+ 06 yyyy yyyy yyyy yyyy y = ypos
+ */
+
+ while( source >= m_spriteram ){
+ int tile_number = source[1];
+ int sx = source[2];
+ int sy = source[3];
+ int colr;
+ int xtiles, ytiles;
+ int ytlim, xtlim;
+ int xflip, yflip;
+ int xstep, ystep;
+ int pri;
+
+ ytlim = (source[0] >> 12) & 0x7;
+ xtlim = (source[0] >> 8 ) & 0x7;
+
+ xflip = (source[0] >> 15) & 0x1;
+ yflip = (source[0] >> 11) & 0x1;
+
+ colr = source[0] & 0x3f;
+
+ pri = (source[0] >> 6) & 3;
+
+ colr |= pri << (14-4);
+
+ ytlim += 1;
+ xtlim += 1;
+
+ xstep = 16;
+ ystep = 16;
+
+ if (xflip)
+ {
+ ystep = -16;
+ sy += ytlim*16-16;
+ }
+
+ if (yflip)
+ {
+ xstep = -16;
+ sx += xtlim*16-16;
+ }
+
+ for (xtiles = 0; xtiles < xtlim; xtiles++)
+ {
+ for (ytiles = 0; ytiles < ytlim; ytiles++)
+ {
+ /* note this wraparound handling could be wrong if some of the COP maths is wrong */
+
+#define ZEROTEAM_MASK_X (0x1ff) // causes a blank square in the corner of zero team, but otherwise the thrusters of the ship in the r2 intro are clipped, using 0x8000 as a sign bit instead of this logic works for r2, but not zero team
+#define ZEROTEAM_MASK_Y (0x1ff)
+
+
+
+ gfx->transpen_raw(
+ m_sprite_bitmap,
+ cliprect,
+ tile_number,
+ colr << 4,
+ yflip,xflip,
+ (sx+xstep*xtiles)&ZEROTEAM_MASK_X,(sy+ystep*ytiles)&ZEROTEAM_MASK_Y, 15);
+
+
+ gfx->transpen_raw(
+ m_sprite_bitmap,
+ cliprect,
+ tile_number,
+ colr << 4,
+ yflip,xflip,
+ ((sx+xstep*xtiles)&ZEROTEAM_MASK_X)-0x200,(sy+ystep*ytiles)&ZEROTEAM_MASK_Y, 15);
+
+
+ gfx->transpen_raw(
+ m_sprite_bitmap,
+ cliprect,
+ tile_number,
+ colr << 4,
+ yflip,xflip,
+ (sx+xstep*xtiles)&ZEROTEAM_MASK_X,((sy+ystep*ytiles)&ZEROTEAM_MASK_Y)-0x200, 15);
+
+
+ gfx->transpen_raw(
+ m_sprite_bitmap,
+ cliprect,
+ tile_number,
+ colr << 4,
+ yflip,xflip,
+ ((sx+xstep*xtiles)&ZEROTEAM_MASK_X)-0x200,((sy+ystep*ytiles)&ZEROTEAM_MASK_Y)-0x200, 15);
+
+
+ tile_number++;
+ }
+ }
+
+ source -= 4;
+ }
+
+}
+
+WRITE16_MEMBER(raiden2_state::background_w)
+{
+ COMBINE_DATA(&m_back_data[offset]);
+ m_background_layer->mark_tile_dirty(offset);
+}
+
+WRITE16_MEMBER(raiden2_state::midground_w)
+{
+ COMBINE_DATA(&m_mid_data[offset]);
+ m_midground_layer->mark_tile_dirty(offset);
+}
+
+WRITE16_MEMBER(raiden2_state::foreground_w)
+{
+ COMBINE_DATA(&m_fore_data[offset]);
+ m_foreground_layer->mark_tile_dirty(offset);
+}
+
+WRITE16_MEMBER(raiden2_state::text_w)
+{
+ COMBINE_DATA(&m_text_data[offset]);
+ m_text_layer->mark_tile_dirty(offset);
+}
+
+WRITE16_MEMBER(raiden2_state::tilemap_enable_w)
+{
+ COMBINE_DATA(&m_tilemap_enable);
+}
+
+WRITE16_MEMBER(raiden2_state::tile_scroll_w)
+{
+ tilemap_t *tm = nullptr;
+ switch(offset/2) {
+ case 0: tm = m_background_layer; break;
+ case 1: tm = m_midground_layer; break;
+ case 2: tm = m_foreground_layer; break;
+ default: assert(0); break;
+ }
+
+ COMBINE_DATA(&m_scrollvals[offset]);
+ data = m_scrollvals[offset];
+
+ if(offset & 1)
+ tm->set_scrolly(0, data);
+ else
+ tm->set_scrollx(0, data);
+}
+
+WRITE8_MEMBER(raiden2_state::tile_bank_01_w)
+{
+ int new_bank;
+ new_bank = 0 | ((data & 1)<<1);
+ if(new_bank != m_bg_bank) {
+ m_bg_bank = new_bank;
+ m_background_layer->mark_all_dirty();
+ }
+
+ new_bank = 1 | (data & 2);
+ if(new_bank != m_mid_bank) {
+ m_mid_bank = new_bank;
+ m_midground_layer->mark_all_dirty();
+ }
+}
+
+READ16_MEMBER(raiden2_state::cop_tile_bank_2_r)
+{
+ return m_cop_bank;
+}
+
+WRITE16_MEMBER(raiden2_state::cop_tile_bank_2_w)
+{
+ COMBINE_DATA(&m_cop_bank);
+
+ if(ACCESSING_BITS_8_15) {
+ int new_bank = 4 | (data >> 14);
+ if(new_bank != m_fg_bank) {
+ m_fg_bank = new_bank;
+ m_foreground_layer->mark_all_dirty();
+ }
+ }
+}
+
+WRITE16_MEMBER(raiden2_state::raidendx_cop_bank_2_w)
+{
+ COMBINE_DATA(&m_cop_bank);
+
+ int new_bank = 4 | ((m_cop_bank >> 4) & 3);
+ if(new_bank != m_fg_bank) {
+ m_fg_bank = new_bank;
+ m_foreground_layer->mark_all_dirty();
+ }
+
+ /* mainbank2 coming from 6c9 ? */
+ int bb = m_cop_bank >> 12;
+ m_mainbank[0]->set_entry(bb + 16);
+ m_mainbank[1]->set_entry(3);
+}
+
+
+TILE_GET_INFO_MEMBER(raiden2_state::get_back_tile_info)
+{
+ int tile = m_back_data[tile_index];
+ int color = (tile >> 12) | (0 << 4);
+
+ tile = (tile & 0xfff) | (m_bg_bank << 12);
+
+ SET_TILE_INFO_MEMBER(1,tile+0x0000,color,0);
+}
+
+TILE_GET_INFO_MEMBER(raiden2_state::get_mid_tile_info)
+{
+ int tile = m_mid_data[tile_index];
+ int color = (tile >> 12) | (2 << 4);
+
+ tile = (tile & 0xfff) | (m_mid_bank << 12);
+
+ SET_TILE_INFO_MEMBER(1,tile,color,0);
+}
+
+TILE_GET_INFO_MEMBER(raiden2_state::get_fore_tile_info)
+{
+ int tile = m_fore_data[tile_index];
+ int color = (tile >> 12) | (1 << 4);
+
+ tile = (tile & 0xfff) | (m_fg_bank << 12);
+
+ SET_TILE_INFO_MEMBER(1,tile,color,0);
+}
+
+TILE_GET_INFO_MEMBER(raiden2_state::get_text_tile_info)
+{
+ int tile = m_text_data[tile_index];
+ int color = (tile>>12)&0xf;
+
+ tile &= 0xfff;
+
+ SET_TILE_INFO_MEMBER(0,tile + m_tx_bank * 0x1000,color,0);
+}
+
+void raiden2_state::video_start()
+{
+ m_screen->register_screen_bitmap(m_tile_bitmap);
+ m_screen->register_screen_bitmap(m_sprite_bitmap);
+
+ m_back_data = make_unique_clear<uint16_t[]>(0x800/2);
+ m_fore_data = make_unique_clear<uint16_t[]>(0x800/2);
+ m_mid_data = make_unique_clear<uint16_t[]>(0x800/2);
+ m_text_data = make_unique_clear<uint16_t[]>(0x1000/2);
+ m_palette_data = make_unique_clear<uint16_t[]>(0x1000/2);
+ m_palette->basemem().set(m_palette_data.get(), 0x1000/2 * sizeof(uint16_t), 16, ENDIANNESS_LITTLE, 2);
+
+ save_pointer(NAME(m_back_data), 0x800/2);
+ save_pointer(NAME(m_fore_data), 0x800/2);
+ save_pointer(NAME(m_mid_data), 0x800/2);
+ save_pointer(NAME(m_text_data), 0x1000/2);
+ save_pointer(NAME(m_palette_data), 0x1000/2);
+
+ m_text_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(raiden2_state::get_text_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64,32 );
+ m_background_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(raiden2_state::get_back_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32 );
+ m_midground_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(raiden2_state::get_mid_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32 );
+ m_foreground_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(raiden2_state::get_fore_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32 );
+}
+
+void raiden2_state::blend_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind16 &source, int layer)
+{
+ if(layer == -1)
+ return;
+
+ const pen_t *pens = &m_palette->pen(0);
+ layer <<= 14;
+ for(int y = cliprect.min_y; y <= cliprect.max_y; y++) {
+ const uint16_t *src = &source.pix16(y, cliprect.min_x);
+ uint32_t *dst = &bitmap.pix32(y, cliprect.min_x);
+ for(int x = cliprect.min_x; x <= cliprect.max_x; x++) {
+ uint16_t val = *src++;
+ if((val & 0xc000) == layer && (val & 0x000f) != 0x000f) {
+ val &= 0x07ff;
+
+ if(m_blend_active[val])
+ *dst = alpha_blend_r32(*dst, pens[val], 0x7f);
+ else
+ *dst = pens[val];
+ }
+ dst++;
+ }
+ }
+}
+
+void raiden2_state::tilemap_draw_and_blend(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tilemap)
+{
+ tilemap->draw(screen, m_tile_bitmap, cliprect, 0, 0);
+ blend_layer(bitmap, cliprect, m_tile_bitmap, 0);
+}
+
+uint32_t raiden2_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(m_palette->black_pen(), cliprect);
+ if (!(m_tilemap_enable & 16)) {
+ draw_sprites(cliprect);
+
+ blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[0]);
+ }
+
+ if (!(m_tilemap_enable & 1))
+ tilemap_draw_and_blend(screen, bitmap, cliprect, m_background_layer);
+
+ if (!(m_tilemap_enable & 16))
+ blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[1]);
+
+ if (!(m_tilemap_enable & 2))
+ tilemap_draw_and_blend(screen, bitmap, cliprect, m_midground_layer);
+
+ if (!(m_tilemap_enable & 16))
+ blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[2]);
+
+ if (!(m_tilemap_enable & 4))
+ tilemap_draw_and_blend(screen, bitmap, cliprect, m_foreground_layer);
+
+ if (!(m_tilemap_enable & 16))
+ blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[3]);
+
+ if (!(m_tilemap_enable & 8))
+ tilemap_draw_and_blend(screen, bitmap, cliprect, m_text_layer);
+
+ if (!(m_tilemap_enable & 16))
+ blend_layer(bitmap, cliprect, m_sprite_bitmap, m_cur_spri[4]);
+
+ if (machine().input().code_pressed_once(KEYCODE_Z))
+ if (m_raiden2cop) m_raiden2cop->dump_table();
+
+ return 0;
+}
+
+