mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
taito_b.cpp, tc0180vcu.cpp : Updates/Cleanups (#3668)
* taito_b.cpp, tc0180vcu.cpp : Updates/Cleanups taito_b.cpp : Move tc0180vcu functions into tc0180vcu.cpp, Minor cleanups tc0180vcu.cpp : Minor cleanups, Convert some arrays into required_shared_ptr, Add notes * Fix taito_b.h * taito_b.cpp : Minor cleanups * taito_b.cpp : Reduce unnecessary gfxdecode (in Nastar schematics, TC0180VCU GFX ROM is 32-bit wide(CH0-31 is connected by data bus)) * taito_b.cpp : Remove unused * tc0180vcu.cpp : Internalize gfxdecode
This commit is contained in:
parent
f871b84c9e
commit
f5f123c184
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,10 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Jarek Burczynski
|
||||
#ifndef MAME_INCLUDES_TAITO_B_H
|
||||
#define MAME_INCLUDES_TAITO_B_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/mb87078.h"
|
||||
#include "machine/taitoio.h"
|
||||
#include "video/hd63484.h"
|
||||
@ -10,9 +15,8 @@
|
||||
class taitob_state : public driver_device
|
||||
{
|
||||
public:
|
||||
taitob_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
taitob_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_pixelram(*this, "pixelram"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
@ -23,19 +27,19 @@ public:
|
||||
m_tc0220ioc(*this, "tc0220ioc"),
|
||||
m_tc0510nio(*this, "tc0510nio"),
|
||||
m_mb87078(*this, "mb87078"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette") { }
|
||||
m_palette(*this, "palette"),
|
||||
m_audiobank(*this, "audiobank"),
|
||||
m_eepromout_io(*this, "EEPROMOUT"),
|
||||
m_trackx_io(*this, "TRACKX%u", 1U),
|
||||
m_tracky_io(*this, "TRACKY%u", 1U)
|
||||
{ }
|
||||
|
||||
DECLARE_WRITE8_MEMBER(bankswitch_w);
|
||||
DECLARE_READ16_MEMBER(tracky1_hi_r);
|
||||
DECLARE_READ16_MEMBER(tracky1_lo_r);
|
||||
DECLARE_READ16_MEMBER(trackx1_hi_r);
|
||||
DECLARE_READ16_MEMBER(trackx1_lo_r);
|
||||
DECLARE_READ16_MEMBER(tracky2_hi_r);
|
||||
DECLARE_READ16_MEMBER(tracky2_lo_r);
|
||||
DECLARE_READ16_MEMBER(trackx2_hi_r);
|
||||
DECLARE_READ16_MEMBER(trackx2_lo_r);
|
||||
template<int Player> DECLARE_READ16_MEMBER(tracky_hi_r);
|
||||
template<int Player> DECLARE_READ16_MEMBER(tracky_lo_r);
|
||||
template<int Player> DECLARE_READ16_MEMBER(trackx_hi_r);
|
||||
template<int Player> DECLARE_READ16_MEMBER(trackx_lo_r);
|
||||
DECLARE_WRITE16_MEMBER(gain_control_w);
|
||||
DECLARE_READ16_MEMBER(eep_latch_r);
|
||||
DECLARE_WRITE16_MEMBER(eeprom_w);
|
||||
@ -47,21 +51,15 @@ public:
|
||||
DECLARE_WRITE16_MEMBER(hitice_pixelram_w);
|
||||
DECLARE_WRITE16_MEMBER(hitice_pixel_scroll_w);
|
||||
DECLARE_WRITE16_MEMBER(realpunc_video_ctrl_w);
|
||||
DECLARE_READ16_MEMBER(tc0180vcu_framebuffer_word_r);
|
||||
DECLARE_WRITE16_MEMBER(tc0180vcu_framebuffer_word_w);
|
||||
DECLARE_WRITE8_MEMBER(mb87078_gain_changed);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(realpunc_sensor);
|
||||
void init_taito_b();
|
||||
DECLARE_VIDEO_START(taitob_color_order0);
|
||||
DECLARE_VIDEO_START(taitob_color_order1);
|
||||
DECLARE_VIDEO_START(taitob_color_order2);
|
||||
DECLARE_VIDEO_START(hitice);
|
||||
DECLARE_VIDEO_RESET(hitice);
|
||||
DECLARE_VIDEO_START(realpunc);
|
||||
DECLARE_VIDEO_START(taitob_core);
|
||||
uint32_t screen_update_taitob(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_realpunc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank_taitob);
|
||||
|
||||
void spacedx(machine_config &config);
|
||||
void rambo3(machine_config &config);
|
||||
@ -105,23 +103,17 @@ protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
void tc0180vcu_memrw(address_map &map, u32 addr);
|
||||
|
||||
private:
|
||||
/* memory pointers */
|
||||
required_shared_ptr<uint16_t> m_spriteram;
|
||||
optional_shared_ptr<uint16_t> m_pixelram;
|
||||
|
||||
/* video-related */
|
||||
/* framebuffer is a raw bitmap, remapped as a last step */
|
||||
std::unique_ptr<bitmap_ind16> m_framebuffer[2];
|
||||
std::unique_ptr<bitmap_ind16> m_pixel_bitmap;
|
||||
std::unique_ptr<bitmap_ind16> m_realpunc_bitmap;
|
||||
|
||||
uint16_t m_pixel_scroll[3];
|
||||
|
||||
int m_b_fg_color_base;
|
||||
int m_b_sp_color_base;
|
||||
int m_b_fg_color_base;
|
||||
|
||||
/* misc */
|
||||
uint16_t m_eep_latch;
|
||||
@ -139,13 +131,15 @@ private:
|
||||
optional_device<tc0220ioc_device> m_tc0220ioc;
|
||||
optional_device<tc0510nio_device> m_tc0510nio;
|
||||
optional_device<mb87078_device> m_mb87078;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
required_memory_bank m_audiobank;
|
||||
optional_ioport m_eepromout_io;
|
||||
optional_ioport_array<2> m_trackx_io;
|
||||
optional_ioport_array<2> m_tracky_io;
|
||||
|
||||
void hitice_clear_pixel_bitmap( );
|
||||
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
void draw_framebuffer( bitmap_ind16 &bitmap, const rectangle &cliprect, int priority );
|
||||
};
|
||||
|
||||
class taitob_c_state : public taitob_state
|
||||
@ -155,3 +149,5 @@ public:
|
||||
static constexpr feature_type unemulated_features() { return feature::CAMERA; }
|
||||
void realpunc(machine_config &config);
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_TAITO_B_H
|
@ -39,50 +39,14 @@ WRITE16_MEMBER(taitob_state::realpunc_video_ctrl_w)
|
||||
|
||||
VIDEO_START_MEMBER(taitob_state,taitob_core)
|
||||
{
|
||||
m_framebuffer[0] = std::make_unique<bitmap_ind16>(512, 256);
|
||||
m_framebuffer[1] = std::make_unique<bitmap_ind16>(512, 256);
|
||||
m_pixel_bitmap = nullptr; /* only hitice needs this */
|
||||
|
||||
save_item(NAME(m_pixel_scroll));
|
||||
|
||||
save_item(NAME(*m_framebuffer[0]));
|
||||
save_item(NAME(*m_framebuffer[1]));
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(taitob_state,taitob_color_order0)
|
||||
{
|
||||
/*graphics are shared, only that they use different palette*/
|
||||
/*this is the basic layout used in: Nastar, Ashura Blaster, Hit the Ice, Rambo3, Tetris*/
|
||||
|
||||
/*Note that in both this and color order 1 pixel_color_base/color_granularity is equal to sprites color base. Pure coincidence? */
|
||||
|
||||
m_b_sp_color_base = 0x40 * 16; /*sprites */
|
||||
|
||||
/* bg, fg, tx color_base are set in the tc0180vcu interface */
|
||||
|
||||
VIDEO_START_CALL_MEMBER(taitob_core);
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(taitob_state,taitob_color_order1)
|
||||
{
|
||||
/* this is the reversed layout used in: Crime City, Puzzle Bobble */
|
||||
m_b_sp_color_base = 0x80 * 16;
|
||||
|
||||
VIDEO_START_CALL_MEMBER(taitob_core);
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(taitob_state,taitob_color_order2)
|
||||
{
|
||||
/*this is used in: rambo3a, masterw, silentd, selfeena, ryujin */
|
||||
m_b_sp_color_base = 0x10 * 16;
|
||||
|
||||
VIDEO_START_CALL_MEMBER(taitob_core);
|
||||
}
|
||||
|
||||
|
||||
VIDEO_START_MEMBER(taitob_state,hitice)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(taitob_color_order0);
|
||||
VIDEO_START_CALL_MEMBER(taitob_core);
|
||||
|
||||
m_b_fg_color_base = 0x80; /* hitice also uses this for the pixel_bitmap */
|
||||
|
||||
@ -102,267 +66,13 @@ VIDEO_START_MEMBER(taitob_state,realpunc)
|
||||
{
|
||||
m_realpunc_bitmap = std::make_unique<bitmap_ind16>(m_screen->width(), m_screen->height());
|
||||
|
||||
VIDEO_START_CALL_MEMBER(taitob_color_order0);
|
||||
VIDEO_START_CALL_MEMBER(taitob_core);
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER(taitob_state::tc0180vcu_framebuffer_word_r)
|
||||
{
|
||||
int sy = offset >> 8;
|
||||
int sx = 2 * (offset & 0xff);
|
||||
|
||||
return (m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 0) << 8) | m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 1);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(taitob_state::tc0180vcu_framebuffer_word_w)
|
||||
{
|
||||
int sy = offset >> 8;
|
||||
int sx = 2 * (offset & 0xff);
|
||||
|
||||
if (ACCESSING_BITS_8_15)
|
||||
m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 0) = data >> 8;
|
||||
if (ACCESSING_BITS_0_7)
|
||||
m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 1) = data & 0xff;
|
||||
}
|
||||
|
||||
|
||||
void taitob_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
|
||||
{
|
||||
/* Sprite format: (16 bytes per sprite)
|
||||
offs: bits:
|
||||
0000: 0xxxxxxxxxxxxxxx: tile code - 0x0000 to 0x7fff in qzshowby
|
||||
0002: 0000000000xxxxxx: color (0x00 - 0x3f)
|
||||
x000000000000000: flipy
|
||||
0x00000000000000: flipx
|
||||
00????????000000: unused ?
|
||||
0004: xxxxxx0000000000: doesn't matter - some games (eg nastar) fill this with sign bit, some (eg ashura) do not
|
||||
000000xxxxxxxxxx: x-coordinate 10 bits signed (all zero for sprites forming up a big sprite, except for the first one)
|
||||
0006: xxxxxx0000000000: doesn't matter - same as x
|
||||
000000xxxxxxxxxx: y-coordinate 10 bits signed (same as x)
|
||||
0008: xxxxxxxx00000000: sprite x-zoom level
|
||||
00000000xxxxxxxx: sprite y-zoom level
|
||||
0x00 - non scaled = 100%
|
||||
0x80 - scaled to 50%
|
||||
0xc0 - scaled to 25%
|
||||
0xe0 - scaled to 12.5%
|
||||
0xff - scaled to zero pixels size (off)
|
||||
Sprite zoom is used in Ashura Blaster just in the beginning
|
||||
where you can see a big choplifter and a japanese title.
|
||||
This japanese title is a scaled sprite.
|
||||
It is used in Crime City also at the end of the third level (in the garage)
|
||||
where there are four columns on the sides of the screen
|
||||
Heaviest usage is in Rambo 3 - almost every sprite in game is scaled
|
||||
000a: xxxxxxxx00000000: x-sprites number (big sprite) decremented by one
|
||||
00000000xxxxxxxx: y-sprites number (big sprite) decremented by one
|
||||
000c - 000f: unused
|
||||
*/
|
||||
|
||||
int x, y, xlatch = 0, ylatch = 0, x_no = 0, y_no = 0, x_num = 0, y_num = 0, big_sprite = 0;
|
||||
int offs, code, color, flipx, flipy;
|
||||
uint32_t data, zoomx, zoomy, zx, zy, zoomxlatch = 0, zoomylatch = 0;
|
||||
|
||||
for (offs = (0x1980 - 16) / 2; offs >=0; offs -= 8)
|
||||
{
|
||||
code = m_spriteram[offs];
|
||||
|
||||
color = m_spriteram[offs + 1];
|
||||
flipx = color & 0x4000;
|
||||
flipy = color & 0x8000;
|
||||
#if 0
|
||||
/*check the unknown bits*/
|
||||
if (color & 0x3fc0)
|
||||
{
|
||||
logerror("sprite color (taitob)=%4x ofs=%4x\n", color, offs);
|
||||
color = machine().rand() & 0x3f;
|
||||
}
|
||||
#endif
|
||||
color = (color & 0x3f) * 16;
|
||||
|
||||
x = m_spriteram[offs + 2] & 0x3ff;
|
||||
y = m_spriteram[offs + 3] & 0x3ff;
|
||||
if (x >= 0x200) x -= 0x400;
|
||||
if (y >= 0x200) y -= 0x400;
|
||||
|
||||
data = m_spriteram[offs + 5];
|
||||
if (data)
|
||||
{
|
||||
if (!big_sprite)
|
||||
{
|
||||
x_num = (data >> 8) & 0xff;
|
||||
y_num = (data >> 0) & 0xff;
|
||||
x_no = 0;
|
||||
y_no = 0;
|
||||
xlatch = x;
|
||||
ylatch = y;
|
||||
data = m_spriteram[offs + 4];
|
||||
zoomxlatch = (data >> 8) & 0xff;
|
||||
zoomylatch = (data >> 0) & 0xff;
|
||||
big_sprite = 1;
|
||||
}
|
||||
}
|
||||
|
||||
data = m_spriteram[offs + 4];
|
||||
zoomx = (data >> 8) & 0xff;
|
||||
zoomy = (data >> 0) & 0xff;
|
||||
zx = (0x100 - zoomx) / 16;
|
||||
zy = (0x100 - zoomy) / 16;
|
||||
|
||||
if (big_sprite)
|
||||
{
|
||||
zoomx = zoomxlatch;
|
||||
zoomy = zoomylatch;
|
||||
|
||||
/* Note: like taito_f2.c, this zoom implementation is wrong,
|
||||
chopped up into 16x16 sections instead of one sprite. This
|
||||
is especially visible in rambo3. */
|
||||
|
||||
x = xlatch + (x_no * (0xff - zoomx) + 15) / 16;
|
||||
y = ylatch + (y_no * (0xff - zoomy) + 15) / 16;
|
||||
zx = xlatch + ((x_no + 1) * (0xff - zoomx) + 15) / 16 - x;
|
||||
zy = ylatch + ((y_no + 1) * (0xff - zoomy) + 15) / 16 - y;
|
||||
y_no++;
|
||||
|
||||
if (y_no > y_num)
|
||||
{
|
||||
y_no = 0;
|
||||
x_no++;
|
||||
|
||||
if (x_no > x_num)
|
||||
big_sprite = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( zoomx || zoomy )
|
||||
{
|
||||
m_gfxdecode->gfx(1)->zoom_transpen_raw(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
flipx,flipy,
|
||||
x,y,
|
||||
(zx << 16) / 16,(zy << 16) / 16,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gfxdecode->gfx(1)->transpen_raw(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
flipx,flipy,
|
||||
x,y,
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void taitob_state::draw_framebuffer( bitmap_ind16 &bitmap, const rectangle &cliprect, int priority )
|
||||
{
|
||||
rectangle myclip = cliprect;
|
||||
int x, y;
|
||||
address_space &space = machine().dummy_space();
|
||||
uint8_t video_control = m_tc0180vcu->get_videoctrl(space, 0);
|
||||
uint8_t framebuffer_page = m_tc0180vcu->get_fb_page(space, 0);
|
||||
|
||||
g_profiler.start(PROFILER_USER1);
|
||||
|
||||
priority <<= 4;
|
||||
|
||||
if (video_control & 0x08)
|
||||
{
|
||||
if (priority)
|
||||
{
|
||||
g_profiler.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (video_control & 0x10) /*flip screen*/
|
||||
{
|
||||
/*popmessage("1. X[%3i;%3i] Y[%3i;%3i]", myclip.min_x, myclip.max_x, myclip.min_y, myclip.max_y);*/
|
||||
for (y = myclip.min_y; y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst;
|
||||
|
||||
dst = &bitmap.pix16(bitmap.height()-1-y, myclip.max_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0)
|
||||
*dst = m_b_sp_color_base + c;
|
||||
|
||||
dst--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = myclip.min_y; y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst = &bitmap.pix16(y, myclip.min_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0)
|
||||
*dst = m_b_sp_color_base + c;
|
||||
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (video_control & 0x10) /*flip screen*/
|
||||
{
|
||||
/*popmessage("3. X[%3i;%3i] Y[%3i;%3i]", myclip.min_x, myclip.max_x, myclip.min_y, myclip.max_y);*/
|
||||
for (y = myclip.min_y ;y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst;
|
||||
|
||||
dst = &bitmap.pix16(bitmap.height()-1-y, myclip.max_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0 && (c & 0x10) == priority)
|
||||
*dst = m_b_sp_color_base + c;
|
||||
|
||||
dst--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = myclip.min_y; y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst = &bitmap.pix16(y, myclip.min_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0 && (c & 0x10) == priority)
|
||||
*dst = m_b_sp_color_base + c;
|
||||
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_profiler.stop();
|
||||
}
|
||||
|
||||
uint32_t taitob_state::screen_update_taitob(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
address_space &space = machine().dummy_space();
|
||||
uint8_t video_control = m_tc0180vcu->get_videoctrl(space, 0);
|
||||
uint8_t const video_control = m_tc0180vcu->get_videoctrl();
|
||||
|
||||
if ((video_control & 0x20) == 0)
|
||||
{
|
||||
@ -373,7 +83,7 @@ uint32_t taitob_state::screen_update_taitob(screen_device &screen, bitmap_ind16
|
||||
/* Draw playfields */
|
||||
m_tc0180vcu->tilemap_draw(screen, bitmap, cliprect, 0, 1);
|
||||
|
||||
draw_framebuffer(bitmap, cliprect, 1);
|
||||
m_tc0180vcu->draw_framebuffer(bitmap, cliprect, 1);
|
||||
|
||||
m_tc0180vcu->tilemap_draw(screen, bitmap, cliprect, 1, 0);
|
||||
|
||||
@ -388,7 +98,7 @@ uint32_t taitob_state::screen_update_taitob(screen_device &screen, bitmap_ind16
|
||||
copyscrollbitmap_trans(bitmap, *m_pixel_bitmap, 1, &scrollx, 1, &scrolly, cliprect, m_b_fg_color_base * 16);
|
||||
}
|
||||
|
||||
draw_framebuffer(bitmap, cliprect, 0);
|
||||
m_tc0180vcu->draw_framebuffer(bitmap, cliprect, 0);
|
||||
|
||||
m_tc0180vcu->tilemap_draw(screen, bitmap, cliprect, 2, 0);
|
||||
|
||||
@ -399,9 +109,8 @@ uint32_t taitob_state::screen_update_taitob(screen_device &screen, bitmap_ind16
|
||||
|
||||
uint32_t taitob_state::screen_update_realpunc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
address_space &space = machine().dummy_space();
|
||||
const pen_t *palette = m_palette->pens();
|
||||
uint8_t video_control = m_tc0180vcu->get_videoctrl(space, 0);
|
||||
uint8_t const video_control = m_tc0180vcu->get_videoctrl();
|
||||
int x, y;
|
||||
|
||||
/* Video blanked? */
|
||||
@ -414,12 +123,12 @@ uint32_t taitob_state::screen_update_realpunc(screen_device &screen, bitmap_rgb3
|
||||
/* Draw the palettized playfields to an indexed bitmap */
|
||||
m_tc0180vcu->tilemap_draw(screen, *m_realpunc_bitmap, cliprect, 0, 1);
|
||||
|
||||
draw_framebuffer(*m_realpunc_bitmap, cliprect, 1);
|
||||
m_tc0180vcu->draw_framebuffer(*m_realpunc_bitmap, cliprect, 1);
|
||||
|
||||
m_tc0180vcu->tilemap_draw(screen, *m_realpunc_bitmap, cliprect, 1, 0);
|
||||
|
||||
if (m_realpunc_video_ctrl & 0x0001)
|
||||
draw_framebuffer(*m_realpunc_bitmap, cliprect, 0);
|
||||
m_tc0180vcu->draw_framebuffer(*m_realpunc_bitmap, cliprect, 0);
|
||||
|
||||
/* Copy the intermediate bitmap to the output bitmap, applying the palette */
|
||||
for (y = 0; y <= cliprect.max_y; y++)
|
||||
@ -464,7 +173,7 @@ uint32_t taitob_state::screen_update_realpunc(screen_device &screen, bitmap_rgb3
|
||||
m_realpunc_bitmap->fill(0, cliprect);
|
||||
|
||||
if (!(m_realpunc_video_ctrl & 0x0001))
|
||||
draw_framebuffer(*m_realpunc_bitmap, cliprect, 0);
|
||||
m_tc0180vcu->draw_framebuffer(*m_realpunc_bitmap, cliprect, 0);
|
||||
|
||||
m_tc0180vcu->tilemap_draw(screen, *m_realpunc_bitmap, cliprect, 2, 0);
|
||||
|
||||
@ -481,26 +190,3 @@ uint32_t taitob_state::screen_update_realpunc(screen_device &screen, bitmap_rgb3
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(taitob_state::screen_vblank_taitob)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
address_space &space = machine().dummy_space();
|
||||
uint8_t video_control = m_tc0180vcu->get_videoctrl(space, 0);
|
||||
uint8_t framebuffer_page = m_tc0180vcu->get_fb_page(space, 0);
|
||||
|
||||
if (~video_control & 0x01)
|
||||
m_framebuffer[framebuffer_page]->fill(0, m_screen->visible_area());
|
||||
|
||||
if (~video_control & 0x80)
|
||||
{
|
||||
framebuffer_page ^= 1;
|
||||
m_tc0180vcu->set_fb_page(space, 0, framebuffer_page);
|
||||
}
|
||||
|
||||
draw_sprites(*m_framebuffer[framebuffer_page], m_screen->visible_area());
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,71 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nicola Salmoria
|
||||
/* Taito TC0180VCU */
|
||||
// Sprite/Framebuffer emulation by Jarek Burczynski (from taito_b.cpp)
|
||||
|
||||
#include "emu.h"
|
||||
#include "tc0180vcu.h"
|
||||
#include "screen.h"
|
||||
|
||||
#define TC0180VCU_RAM_SIZE 0x10000
|
||||
#define TC0180VCU_SCROLLRAM_SIZE 0x0800
|
||||
//#define TC0180VCU_RAM_SIZE 0x10000
|
||||
//#define TC0180VCU_SCROLLRAM_SIZE 0x0800
|
||||
|
||||
const gfx_layout tc0180vcu_device::charlayout =
|
||||
{
|
||||
8,8,
|
||||
RGN_FRAC(1,2),
|
||||
4,
|
||||
{ 0, 8, RGN_FRAC(1,2), RGN_FRAC(1,2)+8 },
|
||||
{ STEP8(0,1) },
|
||||
{ STEP8(0,8*2) },
|
||||
16*8
|
||||
};
|
||||
|
||||
const gfx_layout tc0180vcu_device::tilelayout =
|
||||
{
|
||||
16,16,
|
||||
RGN_FRAC(1,2),
|
||||
4,
|
||||
{ 0, 8, RGN_FRAC(1,2), RGN_FRAC(1,2)+8 },
|
||||
{ STEP8(0,1), STEP8(8*8*2,1) },
|
||||
{ STEP8(0,8*2), STEP8(8*8*2*2,8*2) },
|
||||
64*8
|
||||
};
|
||||
|
||||
GFXDECODE_MEMBER( tc0180vcu_device::gfxinfo )
|
||||
GFXDECODE_DEVICE( DEVICE_SELF, 0, charlayout, 0, 256 )
|
||||
GFXDECODE_DEVICE( DEVICE_SELF, 0, tilelayout, 0, 256 )
|
||||
GFXDECODE_END
|
||||
|
||||
void tc0180vcu_device::tc0180vcu_memrw(address_map &map)
|
||||
{
|
||||
map(0x00000, 0x0ffff).ram().w(FUNC(tc0180vcu_device::word_w)).share("vram");
|
||||
map(0x10000, 0x1197f).ram().share("spriteram");
|
||||
map(0x11980, 0x137ff).ram();
|
||||
map(0x13800, 0x13fff).ram().share("scrollram");
|
||||
map(0x18000, 0x1801f).ram().w(FUNC(tc0180vcu_device::ctrl_w)).share("ctrl");
|
||||
map(0x40000, 0x7ffff).rw(FUNC(tc0180vcu_device::framebuffer_word_r), FUNC(tc0180vcu_device::framebuffer_word_w));
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_TYPE(TC0180VCU, tc0180vcu_device, "tc0180vcu", "Taito TC0180VCU")
|
||||
|
||||
tc0180vcu_device::tc0180vcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, TC0180VCU, tag, owner, clock),
|
||||
tc0180vcu_device::tc0180vcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, TC0180VCU, tag, owner, clock),
|
||||
device_gfx_interface(mconfig, *this, gfxinfo),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_ram(nullptr),
|
||||
//m_scrollram(nullptr),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
m_vram(*this, "vram"),
|
||||
m_scrollram(*this, "scrollram"),
|
||||
m_ctrl(*this, "ctrl"),
|
||||
//m_bg_rambank(0),
|
||||
//m_fg_rambank(0),
|
||||
//m_tx_rambank(0),
|
||||
m_framebuffer_page(0),
|
||||
m_video_control(0),
|
||||
m_fb_color_base(0),
|
||||
m_bg_color_base(0),
|
||||
m_fg_color_base(0),
|
||||
m_tx_color_base(0),
|
||||
m_gfxdecode(*this, finder_base::DUMMY_TAG),
|
||||
m_inth_callback(*this),
|
||||
m_intl_callback(*this),
|
||||
m_intl_timer(nullptr)
|
||||
@ -50,25 +90,19 @@ void tc0180vcu_device::device_resolve_objects()
|
||||
|
||||
void tc0180vcu_device::device_start()
|
||||
{
|
||||
if(!m_gfxdecode->started())
|
||||
throw device_missing_dependencies();
|
||||
|
||||
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0180vcu_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
|
||||
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0180vcu_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
|
||||
m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0180vcu_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
|
||||
m_tilemap[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(tc0180vcu_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
|
||||
m_tilemap[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(tc0180vcu_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
|
||||
m_tilemap[2] = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(tc0180vcu_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
|
||||
|
||||
m_tilemap[1]->set_transparent_pen(0);
|
||||
m_tilemap[2]->set_transparent_pen(0);
|
||||
|
||||
m_ram = make_unique_clear<uint16_t[]>(TC0180VCU_RAM_SIZE / 2);
|
||||
m_scrollram = make_unique_clear<uint16_t[]>(TC0180VCU_SCROLLRAM_SIZE / 2);
|
||||
m_framebuffer[0] = std::make_unique<bitmap_ind16>(512, 256);
|
||||
m_framebuffer[1] = std::make_unique<bitmap_ind16>(512, 256);
|
||||
|
||||
screen().register_vblank_callback(vblank_state_delegate(&tc0180vcu_device::vblank_callback, this));
|
||||
m_intl_timer = timer_alloc(TIMER_INTL);
|
||||
|
||||
save_pointer(NAME(m_ram.get()), TC0180VCU_RAM_SIZE / 2);
|
||||
save_pointer(NAME(m_scrollram.get()), TC0180VCU_SCROLLRAM_SIZE / 2);
|
||||
|
||||
save_item(NAME(m_bg_rambank));
|
||||
save_item(NAME(m_fg_rambank));
|
||||
save_item(NAME(m_tx_rambank));
|
||||
@ -76,7 +110,9 @@ void tc0180vcu_device::device_start()
|
||||
save_item(NAME(m_framebuffer_page));
|
||||
|
||||
save_item(NAME(m_video_control));
|
||||
save_item(NAME(m_ctrl));
|
||||
|
||||
save_item(NAME(*m_framebuffer[0]));
|
||||
save_item(NAME(*m_framebuffer[1]));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -187,21 +223,6 @@ void tc0180vcu_device::device_timer(emu_timer &timer, device_timer_id id, int pa
|
||||
*
|
||||
*/
|
||||
|
||||
READ8_MEMBER( tc0180vcu_device::get_fb_page )
|
||||
{
|
||||
return m_framebuffer_page;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( tc0180vcu_device::set_fb_page )
|
||||
{
|
||||
m_framebuffer_page = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER( tc0180vcu_device::get_videoctrl )
|
||||
{
|
||||
return m_video_control;
|
||||
}
|
||||
|
||||
void tc0180vcu_device::video_control( uint8_t data )
|
||||
{
|
||||
#if 0
|
||||
@ -212,23 +233,18 @@ void tc0180vcu_device::video_control( uint8_t data )
|
||||
m_video_control = data;
|
||||
|
||||
if (m_video_control & 0x80)
|
||||
m_framebuffer_page = (~m_video_control & 0x40) >> 6;
|
||||
m_framebuffer_page = BIT(~m_video_control, 6);
|
||||
|
||||
machine().tilemap().set_flip_all((m_video_control & 0x10) ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0 );
|
||||
}
|
||||
|
||||
READ16_MEMBER( tc0180vcu_device::ctrl_r )
|
||||
{
|
||||
return m_ctrl[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( tc0180vcu_device::ctrl_w )
|
||||
{
|
||||
uint16_t oldword = m_ctrl[offset];
|
||||
|
||||
COMBINE_DATA (&m_ctrl[offset]);
|
||||
|
||||
if (oldword != m_ctrl[offset])
|
||||
if (oldword ^ m_ctrl[offset])
|
||||
{
|
||||
if (ACCESSING_BITS_8_15)
|
||||
{
|
||||
@ -262,10 +278,29 @@ WRITE16_MEMBER( tc0180vcu_device::ctrl_w )
|
||||
}
|
||||
}
|
||||
|
||||
READ16_MEMBER(tc0180vcu_device::framebuffer_word_r)
|
||||
{
|
||||
int sy = offset >> 8;
|
||||
int sx = 2 * (offset & 0xff);
|
||||
|
||||
return (m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 0) << 8) | m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 1);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(tc0180vcu_device::framebuffer_word_w)
|
||||
{
|
||||
int sy = offset >> 8;
|
||||
int sx = 2 * (offset & 0xff);
|
||||
|
||||
if (ACCESSING_BITS_8_15)
|
||||
m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 0) = data >> 8;
|
||||
if (ACCESSING_BITS_0_7)
|
||||
m_framebuffer[sy >> 8]->pix16(sy & 0xff, sx + 1) = data & 0xff;
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(tc0180vcu_device::get_bg_tile_info)
|
||||
{
|
||||
int tile = m_ram[tile_index + m_bg_rambank[0]];
|
||||
int color = m_ram[tile_index + m_bg_rambank[1]];
|
||||
int tile = m_vram[tile_index + m_bg_rambank[0]];
|
||||
int color = m_vram[tile_index + m_bg_rambank[1]];
|
||||
|
||||
SET_TILE_INFO_MEMBER(1, tile,
|
||||
m_bg_color_base + (color & 0x3f),
|
||||
@ -274,8 +309,8 @@ TILE_GET_INFO_MEMBER(tc0180vcu_device::get_bg_tile_info)
|
||||
|
||||
TILE_GET_INFO_MEMBER(tc0180vcu_device::get_fg_tile_info)
|
||||
{
|
||||
int tile = m_ram[tile_index + m_fg_rambank[0]];
|
||||
int color = m_ram[tile_index + m_fg_rambank[1]];
|
||||
int tile = m_vram[tile_index + m_fg_rambank[0]];
|
||||
int color = m_vram[tile_index + m_fg_rambank[1]];
|
||||
|
||||
SET_TILE_INFO_MEMBER(1, tile,
|
||||
m_fg_color_base + (color & 0x3f),
|
||||
@ -284,7 +319,7 @@ TILE_GET_INFO_MEMBER(tc0180vcu_device::get_fg_tile_info)
|
||||
|
||||
TILE_GET_INFO_MEMBER(tc0180vcu_device::get_tx_tile_info)
|
||||
{
|
||||
int tile = m_ram[tile_index + m_tx_rambank];
|
||||
int tile = m_vram[tile_index + m_tx_rambank];
|
||||
|
||||
SET_TILE_INFO_MEMBER(0,
|
||||
(tile & 0x07ff) | ((m_ctrl[4 + ((tile & 0x800) >> 11)]>>8) << 11),
|
||||
@ -292,24 +327,9 @@ TILE_GET_INFO_MEMBER(tc0180vcu_device::get_tx_tile_info)
|
||||
0);
|
||||
}
|
||||
|
||||
READ16_MEMBER( tc0180vcu_device::scroll_r )
|
||||
{
|
||||
return m_scrollram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( tc0180vcu_device::scroll_w )
|
||||
{
|
||||
COMBINE_DATA(&m_scrollram[offset]);
|
||||
}
|
||||
|
||||
READ16_MEMBER( tc0180vcu_device::word_r )
|
||||
{
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( tc0180vcu_device::word_w )
|
||||
{
|
||||
COMBINE_DATA(&m_ram[offset]);
|
||||
COMBINE_DATA(&m_vram[offset]);
|
||||
|
||||
if ((offset & 0x7000) == m_fg_rambank[0] || (offset & 0x7000) == m_fg_rambank[1])
|
||||
m_tilemap[1]->mark_tile_dirty(offset & 0x0fff);
|
||||
@ -368,3 +388,249 @@ void tc0180vcu_device::tilemap_draw( screen_device &screen, bitmap_ind16 &bitmap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tc0180vcu_device::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
|
||||
{
|
||||
/* Sprite format: (16 bytes per sprite)
|
||||
offs: bits:
|
||||
0000: 0xxxxxxxxxxxxxxx: tile code - 0x0000 to 0x7fff in qzshowby
|
||||
0002: 0000000000xxxxxx: color (0x00 - 0x3f)
|
||||
x000000000000000: flipy
|
||||
0x00000000000000: flipx
|
||||
00????????000000: unused ?
|
||||
0004: xxxxxx0000000000: doesn't matter - some games (eg nastar) fill this with sign bit, some (eg ashura) do not
|
||||
000000xxxxxxxxxx: x-coordinate 10 bits signed (all zero for sprites forming up a big sprite, except for the first one)
|
||||
0006: xxxxxx0000000000: doesn't matter - same as x
|
||||
000000xxxxxxxxxx: y-coordinate 10 bits signed (same as x)
|
||||
0008: xxxxxxxx00000000: sprite x-zoom level
|
||||
00000000xxxxxxxx: sprite y-zoom level
|
||||
0x00 - non scaled = 100%
|
||||
0x80 - scaled to 50%
|
||||
0xc0 - scaled to 25%
|
||||
0xe0 - scaled to 12.5%
|
||||
0xff - scaled to zero pixels size (off)
|
||||
Sprite zoom is used in Ashura Blaster just in the beginning
|
||||
where you can see a big choplifter and a japanese title.
|
||||
This japanese title is a scaled sprite.
|
||||
It is used in Crime City also at the end of the third level (in the garage)
|
||||
where there are four columns on the sides of the screen
|
||||
Heaviest usage is in Rambo 3 - almost every sprite in game is scaled
|
||||
000a: xxxxxxxx00000000: x-sprites number (big sprite) decremented by one
|
||||
00000000xxxxxxxx: y-sprites number (big sprite) decremented by one
|
||||
000c - 000f: unused
|
||||
*/
|
||||
|
||||
int x, y, xlatch = 0, ylatch = 0, x_no = 0, y_no = 0, x_num = 0, y_num = 0, big_sprite = 0;
|
||||
int offs, code, color, flipx, flipy;
|
||||
uint32_t data, zoomx, zoomy, zx, zy, zoomxlatch = 0, zoomylatch = 0;
|
||||
|
||||
for (offs = (0x1980 - 16) / 2; offs >=0; offs -= 8)
|
||||
{
|
||||
code = m_spriteram[offs];
|
||||
|
||||
color = m_spriteram[offs + 1];
|
||||
flipx = color & 0x4000;
|
||||
flipy = color & 0x8000;
|
||||
#if 0
|
||||
/*check the unknown bits*/
|
||||
if (color & 0x3fc0)
|
||||
{
|
||||
logerror("sprite color (taitob)=%4x ofs=%4x\n", color, offs);
|
||||
color = machine().rand() & 0x3f;
|
||||
}
|
||||
#endif
|
||||
color = (color & 0x3f) * 16;
|
||||
|
||||
x = m_spriteram[offs + 2] & 0x3ff;
|
||||
y = m_spriteram[offs + 3] & 0x3ff;
|
||||
if (x >= 0x200) x -= 0x400;
|
||||
if (y >= 0x200) y -= 0x400;
|
||||
|
||||
data = m_spriteram[offs + 5];
|
||||
if (data)
|
||||
{
|
||||
if (!big_sprite)
|
||||
{
|
||||
x_num = (data >> 8) & 0xff;
|
||||
y_num = (data >> 0) & 0xff;
|
||||
x_no = 0;
|
||||
y_no = 0;
|
||||
xlatch = x;
|
||||
ylatch = y;
|
||||
data = m_spriteram[offs + 4];
|
||||
zoomxlatch = (data >> 8) & 0xff;
|
||||
zoomylatch = (data >> 0) & 0xff;
|
||||
big_sprite = 1;
|
||||
}
|
||||
}
|
||||
|
||||
data = m_spriteram[offs + 4];
|
||||
zoomx = (data >> 8) & 0xff;
|
||||
zoomy = (data >> 0) & 0xff;
|
||||
zx = (0x100 - zoomx) / 16;
|
||||
zy = (0x100 - zoomy) / 16;
|
||||
|
||||
if (big_sprite)
|
||||
{
|
||||
zoomx = zoomxlatch;
|
||||
zoomy = zoomylatch;
|
||||
|
||||
/* Note: like taito_f2.cpp, this zoom implementation is wrong,
|
||||
chopped up into 16x16 sections instead of one sprite. This
|
||||
is especially visible in rambo3. */
|
||||
|
||||
x = xlatch + (x_no * (0xff - zoomx) + 15) / 16;
|
||||
y = ylatch + (y_no * (0xff - zoomy) + 15) / 16;
|
||||
zx = xlatch + ((x_no + 1) * (0xff - zoomx) + 15) / 16 - x;
|
||||
zy = ylatch + ((y_no + 1) * (0xff - zoomy) + 15) / 16 - y;
|
||||
y_no++;
|
||||
|
||||
if (y_no > y_num)
|
||||
{
|
||||
y_no = 0;
|
||||
x_no++;
|
||||
|
||||
if (x_no > x_num)
|
||||
big_sprite = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( zoomx || zoomy )
|
||||
{
|
||||
gfx(1)->zoom_transpen_raw(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
flipx,flipy,
|
||||
x,y,
|
||||
(zx << 16) / 16,(zy << 16) / 16,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx(1)->transpen_raw(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
flipx,flipy,
|
||||
x,y,
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tc0180vcu_device::draw_framebuffer( bitmap_ind16 &bitmap, const rectangle &cliprect, int priority )
|
||||
{
|
||||
rectangle myclip = cliprect;
|
||||
int x, y;
|
||||
|
||||
g_profiler.start(PROFILER_USER1);
|
||||
|
||||
priority <<= 4;
|
||||
|
||||
if (m_video_control & 0x08)
|
||||
{
|
||||
if (priority)
|
||||
{
|
||||
g_profiler.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_video_control & 0x10) /*flip screen*/
|
||||
{
|
||||
/*popmessage("1. X[%3i;%3i] Y[%3i;%3i]", myclip.min_x, myclip.max_x, myclip.min_y, myclip.max_y);*/
|
||||
for (y = myclip.min_y; y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[m_framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst;
|
||||
|
||||
dst = &bitmap.pix16(bitmap.height()-1-y, myclip.max_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0)
|
||||
*dst = m_fb_color_base + c;
|
||||
|
||||
dst--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = myclip.min_y; y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[m_framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst = &bitmap.pix16(y, myclip.min_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0)
|
||||
*dst = m_fb_color_base + c;
|
||||
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_video_control & 0x10) /*flip screen*/
|
||||
{
|
||||
/*popmessage("3. X[%3i;%3i] Y[%3i;%3i]", myclip.min_x, myclip.max_x, myclip.min_y, myclip.max_y);*/
|
||||
for (y = myclip.min_y ;y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[m_framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst;
|
||||
|
||||
dst = &bitmap.pix16(bitmap.height()-1-y, myclip.max_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0 && (c & 0x10) == priority)
|
||||
*dst = m_fb_color_base + c;
|
||||
|
||||
dst--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = myclip.min_y; y <= myclip.max_y; y++)
|
||||
{
|
||||
uint16_t *src = &m_framebuffer[m_framebuffer_page]->pix16(y, myclip.min_x);
|
||||
uint16_t *dst = &bitmap.pix16(y, myclip.min_x);
|
||||
|
||||
for (x = myclip.min_x; x <= myclip.max_x; x++)
|
||||
{
|
||||
uint16_t c = *src++;
|
||||
|
||||
if (c != 0 && (c & 0x10) == priority)
|
||||
*dst = m_fb_color_base + c;
|
||||
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_profiler.stop();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tc0180vcu_device::screen_vblank)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
if (~m_video_control & 0x01)
|
||||
m_framebuffer[m_framebuffer_page]->fill(0, screen().visible_area());
|
||||
|
||||
if (~m_video_control & 0x80)
|
||||
{
|
||||
m_framebuffer_page ^= 1;
|
||||
}
|
||||
|
||||
draw_sprites(*m_framebuffer[m_framebuffer_page], screen().visible_area());
|
||||
}
|
||||
}
|
||||
|
@ -10,30 +10,30 @@
|
||||
#define MCFG_TC0180VCU_INTL_CALLBACK(_write) \
|
||||
devcb = &downcast<tc0180vcu_device &>(*device).set_intl_callback(DEVCB_##_write);
|
||||
|
||||
class tc0180vcu_device : public device_t, public device_video_interface
|
||||
class tc0180vcu_device : public device_t, public device_gfx_interface, public device_video_interface
|
||||
{
|
||||
public:
|
||||
tc0180vcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// configuration
|
||||
void set_gfxdecode_tag(const char *tag) { m_gfxdecode.set_tag(tag); }
|
||||
void set_fb_colorbase(int color) { m_fb_color_base = color * 16; }
|
||||
void set_bg_colorbase(int color) { m_bg_color_base = color; }
|
||||
void set_fg_colorbase(int color) { m_fg_color_base = color; }
|
||||
void set_tx_colorbase(int color) { m_tx_color_base = color; }
|
||||
template <class Object> devcb_base &set_inth_callback(Object &&cb) { return m_inth_callback.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> devcb_base &set_intl_callback(Object &&cb) { return m_intl_callback.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
DECLARE_READ8_MEMBER( get_fb_page );
|
||||
DECLARE_WRITE8_MEMBER( set_fb_page );
|
||||
DECLARE_READ8_MEMBER( get_videoctrl );
|
||||
DECLARE_READ16_MEMBER( ctrl_r );
|
||||
uint8_t get_videoctrl() { return m_video_control; }
|
||||
DECLARE_WRITE16_MEMBER( ctrl_w );
|
||||
DECLARE_READ16_MEMBER( scroll_r );
|
||||
DECLARE_WRITE16_MEMBER( scroll_w );
|
||||
DECLARE_READ16_MEMBER( word_r );
|
||||
DECLARE_WRITE16_MEMBER( word_w );
|
||||
DECLARE_READ16_MEMBER( framebuffer_word_r );
|
||||
DECLARE_WRITE16_MEMBER( framebuffer_word_w );
|
||||
void tilemap_draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int tmap_num, int plane);
|
||||
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
void draw_framebuffer( bitmap_ind16 &bitmap, const rectangle &cliprect, int priority );
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
|
||||
void tc0180vcu_memrw(address_map &map);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_resolve_objects() override;
|
||||
@ -49,10 +49,13 @@ private:
|
||||
void vblank_callback(screen_device &screen, bool state);
|
||||
|
||||
// internal state
|
||||
uint16_t m_ctrl[0x10];
|
||||
|
||||
std::unique_ptr<uint16_t[]> m_ram;
|
||||
std::unique_ptr<uint16_t[]> m_scrollram;
|
||||
required_shared_ptr<uint16_t> m_spriteram;
|
||||
required_shared_ptr<uint16_t> m_vram;
|
||||
required_shared_ptr<uint16_t> m_scrollram;
|
||||
required_shared_ptr<uint16_t> m_ctrl;
|
||||
/* framebuffer is a raw bitmap, remapped as a last step */
|
||||
std::unique_ptr<bitmap_ind16> m_framebuffer[2];
|
||||
|
||||
tilemap_t *m_tilemap[3];
|
||||
|
||||
@ -60,11 +63,13 @@ private:
|
||||
uint8_t m_framebuffer_page;
|
||||
uint8_t m_video_control;
|
||||
|
||||
int m_fb_color_base;
|
||||
int m_bg_color_base;
|
||||
int m_fg_color_base;
|
||||
int m_tx_color_base;
|
||||
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
static const gfx_layout charlayout, tilelayout;
|
||||
DECLARE_GFXDECODE_MEMBER(gfxinfo);
|
||||
|
||||
devcb_write_line m_inth_callback;
|
||||
devcb_write_line m_intl_callback;
|
||||
@ -79,6 +84,9 @@ private:
|
||||
|
||||
DECLARE_DEVICE_TYPE(TC0180VCU, tc0180vcu_device)
|
||||
|
||||
#define MCFG_TC0180VCU_FB_COLORBASE(_color) \
|
||||
downcast<tc0180vcu_device &>(*device).set_fb_colorbase(_color);
|
||||
|
||||
#define MCFG_TC0180VCU_BG_COLORBASE(_color) \
|
||||
downcast<tc0180vcu_device &>(*device).set_bg_colorbase(_color);
|
||||
|
||||
@ -88,7 +96,4 @@ DECLARE_DEVICE_TYPE(TC0180VCU, tc0180vcu_device)
|
||||
#define MCFG_TC0180VCU_TX_COLORBASE(_color) \
|
||||
downcast<tc0180vcu_device &>(*device).set_tx_colorbase(_color);
|
||||
|
||||
#define MCFG_TC0180VCU_GFXDECODE(_gfxtag) \
|
||||
downcast<tc0180vcu_device &>(*device).set_gfxdecode_tag(_gfxtag);
|
||||
|
||||
#endif // MAME_VIDEO_TC0180VCU_H
|
||||
|
Loading…
Reference in New Issue
Block a user