mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Rewritten Imagetek i4100 / i4220 / i4300 video display processor family, hooked it up to metro.cpp [Angelo Salese]
This commit is contained in:
parent
c268543e40
commit
56828c2446
@ -1021,3 +1021,15 @@ if (VIDEOS["BT459"]~=null) then
|
||||
MAME_DIR .. "src/devices/video/bt459.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/imagetek_i4100.h,VIDEOS["I4100"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (VIDEOS["I4100"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/video/imagetek_i4100.cpp",
|
||||
MAME_DIR .. "src/devices/video/imagetek_i4100.h",
|
||||
}
|
||||
end
|
||||
|
1171
src/devices/video/imagetek_i4100.cpp
Normal file
1171
src/devices/video/imagetek_i4100.cpp
Normal file
File diff suppressed because it is too large
Load Diff
229
src/devices/video/imagetek_i4100.h
Normal file
229
src/devices/video/imagetek_i4100.h
Normal file
@ -0,0 +1,229 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Luca Elia,David Haywood,Angelo Salese
|
||||
/***************************************************************************
|
||||
|
||||
Imagetek I4100 / I4220 / I4300 device files
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_VIDEO_I4100_H
|
||||
#define MAME_VIDEO_I4100_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_I4100_ADD(tag) \
|
||||
MCFG_DEVICE_ADD((tag), I4100, (0))
|
||||
|
||||
#define MCFG_I4220_ADD(tag) \
|
||||
MCFG_DEVICE_ADD((tag), I4220, (0))
|
||||
|
||||
#define MCFG_I4300_ADD(tag) \
|
||||
MCFG_DEVICE_ADD((tag), I4300, (0))
|
||||
|
||||
#define MCFG_I4100_GFXDECODE(gfxtag) \
|
||||
imagetek_i4100_device::static_set_gfxdecode_tag(*device, ("^" gfxtag));
|
||||
|
||||
#define MCFG_I4100_BLITTER_END_CALLBACK(_devcb) \
|
||||
devcb = &imagetek_i4100_device::static_set_blitter_irq_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_I4100_TILEMAP_XOFFSETS(_a, _b, _c) \
|
||||
imagetek_i4100_device::static_set_tmap_xoffsets(*device, _a, _b, _c);
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> i4100_device
|
||||
|
||||
class imagetek_i4100_device : public device_t,
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
imagetek_i4100_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_ADDRESS_MAP(map, 16);
|
||||
|
||||
static void static_set_gfxdecode_tag(device_t &device, const char *tag);
|
||||
static void static_set_tmap_xoffsets(device_t &device, int x1, int x2, int x3);
|
||||
|
||||
template <class Object> static devcb_base &static_set_blitter_irq_callback(device_t &device, Object &&cb) { return downcast<imagetek_i4100_device &>(device).m_blit_irq_cb.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
|
||||
// I/O operations
|
||||
DECLARE_READ16_MEMBER( vram_0_r );
|
||||
DECLARE_READ16_MEMBER( vram_1_r );
|
||||
DECLARE_READ16_MEMBER( vram_2_r );
|
||||
DECLARE_WRITE16_MEMBER( vram_0_w );
|
||||
DECLARE_WRITE16_MEMBER( vram_1_w );
|
||||
DECLARE_WRITE16_MEMBER( vram_2_w );
|
||||
DECLARE_READ16_MEMBER( rmw_vram_0_r );
|
||||
DECLARE_READ16_MEMBER( rmw_vram_1_r );
|
||||
DECLARE_READ16_MEMBER( rmw_vram_2_r );
|
||||
DECLARE_WRITE16_MEMBER( rmw_vram_0_w );
|
||||
DECLARE_WRITE16_MEMBER( rmw_vram_1_w );
|
||||
DECLARE_WRITE16_MEMBER( rmw_vram_2_w );
|
||||
DECLARE_READ16_MEMBER( scratchram_r );
|
||||
DECLARE_WRITE16_MEMBER( scratchram_w );
|
||||
DECLARE_READ16_MEMBER( spriteram_r );
|
||||
DECLARE_WRITE16_MEMBER( spriteram_w );
|
||||
DECLARE_READ16_MEMBER( tiletable_r );
|
||||
DECLARE_WRITE16_MEMBER( tiletable_w );
|
||||
DECLARE_READ16_MEMBER( sprite_count_r );
|
||||
DECLARE_WRITE16_MEMBER( sprite_count_w );
|
||||
DECLARE_READ16_MEMBER( sprite_priority_r );
|
||||
DECLARE_WRITE16_MEMBER( sprite_priority_w );
|
||||
DECLARE_READ16_MEMBER( sprite_xoffset_r );
|
||||
DECLARE_WRITE16_MEMBER( sprite_xoffset_w );
|
||||
DECLARE_READ16_MEMBER( sprite_yoffset_r );
|
||||
DECLARE_WRITE16_MEMBER( sprite_yoffset_w );
|
||||
DECLARE_READ16_MEMBER( sprite_color_code_r );
|
||||
DECLARE_WRITE16_MEMBER( sprite_color_code_w );
|
||||
DECLARE_READ16_MEMBER( layer_priority_r );
|
||||
DECLARE_WRITE16_MEMBER( layer_priority_w );
|
||||
DECLARE_READ16_MEMBER( background_color_r );
|
||||
DECLARE_WRITE16_MEMBER( background_color_w );
|
||||
|
||||
DECLARE_READ16_MEMBER( screen_xoffset_r );
|
||||
DECLARE_WRITE16_MEMBER( screen_xoffset_w );
|
||||
DECLARE_READ16_MEMBER( screen_yoffset_r );
|
||||
DECLARE_WRITE16_MEMBER( screen_yoffset_w );
|
||||
|
||||
DECLARE_READ16_MEMBER( window_r );
|
||||
DECLARE_WRITE16_MEMBER( window_w );
|
||||
DECLARE_READ16_MEMBER( scroll_r );
|
||||
DECLARE_WRITE16_MEMBER( scroll_w );
|
||||
|
||||
|
||||
DECLARE_READ16_MEMBER( gfxrom_r );
|
||||
DECLARE_WRITE16_MEMBER( crtc_vert_w );
|
||||
DECLARE_WRITE16_MEMBER( crtc_horz_w );
|
||||
DECLARE_WRITE16_MEMBER( crtc_unlock_w );
|
||||
DECLARE_WRITE16_MEMBER( blitter_w );
|
||||
DECLARE_WRITE16_MEMBER( screen_ctrl_w );
|
||||
DECLARE_WRITE16_MEMBER( rombank_w );
|
||||
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
protected:
|
||||
imagetek_i4100_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool has_ext_tiles);
|
||||
|
||||
// device-level overrides
|
||||
//virtual void device_validity_check(validity_checker &valid) const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
required_shared_ptr<uint16_t> m_vram_0;
|
||||
required_shared_ptr<uint16_t> m_vram_1;
|
||||
required_shared_ptr<uint16_t> m_vram_2;
|
||||
required_shared_ptr<uint16_t> m_scratchram;
|
||||
required_shared_ptr<uint16_t> m_blitter_regs;
|
||||
required_shared_ptr<uint16_t> m_spriteram;
|
||||
required_shared_ptr<uint16_t> m_tiletable;
|
||||
required_shared_ptr<uint16_t> m_window;
|
||||
required_shared_ptr<uint16_t> m_scroll;
|
||||
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_region_ptr<uint8_t> m_gfxrom;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_expanded_gfx1;
|
||||
|
||||
devcb_write_line m_blit_irq_cb;
|
||||
|
||||
uint16_t m_rombank;
|
||||
size_t m_gfxrom_size;
|
||||
bool m_crtc_unlock;
|
||||
uint16_t m_sprite_count;
|
||||
uint16_t m_sprite_priority;
|
||||
uint16_t m_sprite_xoffset,m_sprite_yoffset;
|
||||
uint16_t m_sprite_color_code;
|
||||
uint8_t m_layer_priority[3];
|
||||
uint16_t m_background_color;
|
||||
uint16_t m_screen_xoffset,m_screen_yoffset;
|
||||
bool m_layer_tile_select[3];
|
||||
bool m_screen_blank;
|
||||
bool m_screen_flip;
|
||||
const bool m_support_8bpp, m_support_16x16;
|
||||
int m_tilemap_scrolldx[3];
|
||||
|
||||
void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask );
|
||||
|
||||
enum
|
||||
{
|
||||
TIMER_BLIT_END = 1
|
||||
};
|
||||
|
||||
emu_timer *m_blit_done_timer;
|
||||
|
||||
void draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri );
|
||||
inline uint8_t get_tile_pix( uint16_t code, uint8_t x, uint8_t y, bool big, uint16_t *pix );
|
||||
void draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode,
|
||||
int sx, int sy, int wx, int wy, bool big, uint16_t *tilemapram, int layer );
|
||||
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
void expand_gfx1();
|
||||
|
||||
// A 2048 x 2048 virtual tilemap
|
||||
static constexpr uint32_t BIG_NX = (0x100);
|
||||
static constexpr uint32_t BIG_NY = (0x100);
|
||||
|
||||
// A smaller 512 x 256 window defines the actual tilemap
|
||||
static constexpr uint32_t WIN_NX = (0x40);
|
||||
static constexpr uint32_t WIN_NY = (0x20);
|
||||
|
||||
bool m_inited_hack;
|
||||
};
|
||||
|
||||
class imagetek_i4220_device : public imagetek_i4100_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
imagetek_i4220_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_ADDRESS_MAP(v2_map, 16);
|
||||
|
||||
// needed by Blazing Tornado / Grand Striker 2 for mixing with PSAC
|
||||
// (it's unknown how the chip enables external sync)
|
||||
uint16_t get_background_pen() { return m_background_color; };
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
class imagetek_i4300_device : public imagetek_i4100_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
imagetek_i4300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_ADDRESS_MAP(v3_map, 16);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(I4100, imagetek_i4100_device)
|
||||
DECLARE_DEVICE_TYPE(I4220, imagetek_i4220_device)
|
||||
DECLARE_DEVICE_TYPE(I4300, imagetek_i4300_device)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
#endif // MAME_VIDEO_I4100_H
|
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@
|
||||
#include "sound/ym2151.h"
|
||||
#include "sound/es8712.h"
|
||||
#include "video/k053936.h"
|
||||
#include "video/imagetek_i4100.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "screen.h"
|
||||
@ -20,8 +21,7 @@ public:
|
||||
enum
|
||||
{
|
||||
TIMER_KARATOUR_IRQ,
|
||||
TIMER_MOUJA_IRQ,
|
||||
TIMER_METRO_BLIT_DONE
|
||||
TIMER_MOUJA_IRQ
|
||||
};
|
||||
|
||||
metro_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
@ -31,27 +31,17 @@ public:
|
||||
m_oki(*this, "oki"),
|
||||
m_ymsnd(*this, "ymsnd"),
|
||||
m_essnd(*this, "essnd"),
|
||||
m_vdp(*this, "vdp"),
|
||||
m_vdp2(*this, "vdp2"),
|
||||
m_vdp3(*this, "vdp3"),
|
||||
m_k053936(*this, "k053936") ,
|
||||
m_eeprom(*this, "eeprom"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_soundlatch(*this, "soundlatch"),
|
||||
m_vram_0(*this, "vram_0"),
|
||||
m_vram_1(*this, "vram_1"),
|
||||
m_vram_2(*this, "vram_2"),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
m_spriteregs(*this, "spriteregs"),
|
||||
m_tiletable(*this, "tiletable"),
|
||||
m_blitter_regs(*this, "blitter_regs"),
|
||||
m_scroll(*this, "scroll"),
|
||||
m_window(*this, "window"),
|
||||
m_irq_enable(*this, "irq_enable"),
|
||||
m_irq_levels(*this, "irq_levels"),
|
||||
m_irq_vectors(*this, "irq_vectors"),
|
||||
m_rombank(*this, "rombank"),
|
||||
m_videoregs(*this, "videoregs"),
|
||||
m_screenctrl(*this, "screenctrl"),
|
||||
m_input_sel(*this, "input_sel"),
|
||||
m_k053936_ram(*this, "k053936_ram")
|
||||
{ }
|
||||
@ -70,25 +60,13 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(daitorid_portb_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_coin_lockout_1word_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_coin_lockout_4words_w);
|
||||
DECLARE_READ16_MEMBER(metro_bankedrom_r);
|
||||
DECLARE_WRITE16_MEMBER(metro_blitter_w);
|
||||
DECLARE_READ16_MEMBER(balcube_dsw_r);
|
||||
DECLARE_READ16_MEMBER(karatour_vram_0_r);
|
||||
DECLARE_READ16_MEMBER(karatour_vram_1_r);
|
||||
DECLARE_READ16_MEMBER(karatour_vram_2_r);
|
||||
DECLARE_WRITE16_MEMBER(karatour_vram_0_w);
|
||||
DECLARE_WRITE16_MEMBER(karatour_vram_1_w);
|
||||
DECLARE_WRITE16_MEMBER(karatour_vram_2_w);
|
||||
DECLARE_READ16_MEMBER(gakusai_input_r);
|
||||
DECLARE_WRITE16_MEMBER(blzntrnd_sound_w);
|
||||
DECLARE_WRITE8_MEMBER(blzntrnd_sh_bankswitch_w);
|
||||
DECLARE_WRITE16_MEMBER(puzzlet_irq_enable_w);
|
||||
DECLARE_WRITE16_MEMBER(puzzlet_portb_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_k053936_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_vram_0_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_vram_1_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_vram_2_w);
|
||||
DECLARE_WRITE16_MEMBER(metro_window_w);
|
||||
DECLARE_CUSTOM_INPUT_MEMBER(custom_soundstatus_r);
|
||||
DECLARE_WRITE8_MEMBER(gakusai_oki_bank_hi_w);
|
||||
DECLARE_WRITE8_MEMBER(gakusai_oki_bank_lo_w);
|
||||
@ -98,8 +76,7 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(dokyusp_eeprom_bit_w);
|
||||
DECLARE_WRITE8_MEMBER(dokyusp_eeprom_reset_w);
|
||||
DECLARE_WRITE8_MEMBER(mouja_sound_rombank_w);
|
||||
DECLARE_READ16_MEMBER(gakusai_spriteregs_r);
|
||||
DECLARE_WRITE16_MEMBER(gakusai_spriteregs_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(vdp_blit_end_w);
|
||||
|
||||
// vmetal
|
||||
DECLARE_WRITE8_MEMBER(vmetal_control_w);
|
||||
@ -120,19 +97,13 @@ public:
|
||||
TILE_GET_INFO_MEMBER(metro_k053936_get_tile_info);
|
||||
TILE_GET_INFO_MEMBER(metro_k053936_gstrik2_get_tile_info);
|
||||
TILEMAP_MAPPER_MEMBER(tilemap_scan_gstrik2);
|
||||
DECLARE_VIDEO_START(metro_i4100);
|
||||
DECLARE_VIDEO_START(metro_i4220);
|
||||
DECLARE_VIDEO_START(metro_i4220_dx_tmap);
|
||||
DECLARE_VIDEO_START(metro_i4220_dx_sprite);
|
||||
DECLARE_VIDEO_START(metro_i4300);
|
||||
DECLARE_VIDEO_START(blzntrnd);
|
||||
DECLARE_VIDEO_START(gstrik2);
|
||||
uint32_t screen_update_metro(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_psac_vdp2_mix(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
INTERRUPT_GEN_MEMBER(metro_vblank_interrupt);
|
||||
INTERRUPT_GEN_MEMBER(metro_periodic_interrupt);
|
||||
INTERRUPT_GEN_MEMBER(karatour_interrupt);
|
||||
INTERRUPT_GEN_MEMBER(puzzlet_interrupt);
|
||||
TIMER_CALLBACK_MEMBER(metro_blit_done);
|
||||
IRQ_CALLBACK_MEMBER(metro_irq_callback);
|
||||
DECLARE_READ_LINE_MEMBER(metro_rxd_r);
|
||||
|
||||
@ -147,47 +118,25 @@ private:
|
||||
optional_device<okim6295_device> m_oki;
|
||||
optional_device<device_t> m_ymsnd; // TODO set correct type
|
||||
optional_device<es8712_device> m_essnd;
|
||||
optional_device<imagetek_i4100_device> m_vdp;
|
||||
optional_device<imagetek_i4220_device> m_vdp2;
|
||||
optional_device<imagetek_i4300_device> m_vdp3;
|
||||
|
||||
optional_device<k053936_device> m_k053936;
|
||||
optional_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
optional_device<generic_latch_8_device> m_soundlatch;
|
||||
|
||||
/* memory pointers */
|
||||
optional_shared_ptr<uint16_t> m_vram_0;
|
||||
optional_shared_ptr<uint16_t> m_vram_1;
|
||||
optional_shared_ptr<uint16_t> m_vram_2;
|
||||
required_shared_ptr<uint16_t> m_spriteram;
|
||||
required_shared_ptr<uint16_t> m_spriteregs;
|
||||
optional_shared_ptr<uint16_t> m_tiletable;
|
||||
optional_shared_ptr<uint16_t> m_blitter_regs;
|
||||
optional_shared_ptr<uint16_t> m_scroll;
|
||||
optional_shared_ptr<uint16_t> m_window;
|
||||
optional_shared_ptr<uint16_t> m_irq_enable;
|
||||
optional_shared_ptr<uint16_t> m_irq_levels;
|
||||
optional_shared_ptr<uint16_t> m_irq_vectors;
|
||||
optional_shared_ptr<uint16_t> m_rombank;
|
||||
required_shared_ptr<uint16_t> m_videoregs;
|
||||
optional_shared_ptr<uint16_t> m_screenctrl;
|
||||
optional_shared_ptr<uint16_t> m_input_sel;
|
||||
optional_shared_ptr<uint16_t> m_k053936_ram;
|
||||
|
||||
int m_flip_screen;
|
||||
|
||||
/* video-related */
|
||||
tilemap_t *m_k053936_tilemap;
|
||||
int m_tilemap_scrolldx[3];
|
||||
|
||||
int m_support_8bpp;
|
||||
int m_support_16x16;
|
||||
int m_has_zoom;
|
||||
int m_sprite_xoffs;
|
||||
int m_sprite_yoffs;
|
||||
int m_sprite_xoffs_dx;
|
||||
emu_timer *m_blit_done_timer;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_expanded_gfx1;
|
||||
|
||||
/* irq_related */
|
||||
int m_vblank_bit;
|
||||
@ -209,16 +158,9 @@ private:
|
||||
int m_gakusai_oki_bank_hi;
|
||||
|
||||
void update_irq_state();
|
||||
inline uint8_t get_tile_pix( uint16_t code, uint8_t x, uint8_t y, int big, uint16_t *pix );
|
||||
inline void metro_vram_w( offs_t offset, uint16_t data, uint16_t mem_mask, int layer, uint16_t *vram );
|
||||
void metro_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
void draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, int layers_ctrl );
|
||||
inline int blt_read( const uint8_t *ROM, const int offs );
|
||||
void metro_common();
|
||||
void draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode,
|
||||
int sx, int sy, int wx, int wy, int big, uint16_t *tilemapram, int layer );
|
||||
void expand_gfx1();
|
||||
void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask );
|
||||
void gakusai_oki_bank_set();
|
||||
|
||||
// blazing tornado
|
||||
bitmap_ind16 m_vdp_bitmap;
|
||||
};
|
||||
|
@ -2,54 +2,8 @@
|
||||
// copyright-holders:Luca Elia, David Haywood
|
||||
/***************************************************************************
|
||||
|
||||
-= Metro Games =-
|
||||
|
||||
driver by Luca Elia (l.elia@tin.it)
|
||||
|
||||
|
||||
Note: if MAME_DEBUG is defined, pressing Z with:
|
||||
|
||||
Q Shows Layer 0
|
||||
W Shows Layer 1
|
||||
E Shows Layer 2
|
||||
A Shows Sprites
|
||||
|
||||
Keys can be used together!
|
||||
|
||||
|
||||
[ 3 Scrolling Layers ]
|
||||
|
||||
There is memory for a huge layer, but the actual tilemap
|
||||
is a smaller window (of fixed size) carved from anywhere
|
||||
inside that layer.
|
||||
|
||||
Tile Size: 8 x 8 x 4
|
||||
(later games can switch to 8 x 8 x 8, 16 x 16 x 4/8 at run time)
|
||||
|
||||
Big Layer Size: 2048 x 2048 (8x8 tiles) or 4096 x 4096 (16x16 tiles)
|
||||
|
||||
Tilemap Window Size: 512 x 256 (8x8 tiles) or 1024 x 512 (16x16 tiles)
|
||||
|
||||
The tile codes in memory do not map directly to tiles. They
|
||||
are indexes into a table (with 0x200 entries) that defines
|
||||
a virtual set of tiles for the 3 layers. Each entry in that
|
||||
table adds 16 tiles to the set of available tiles, and decides
|
||||
their color code.
|
||||
|
||||
Tile code with their msbit set are different as they mean:
|
||||
draw a tile filled with a single color (0-fff)
|
||||
|
||||
|
||||
[ 512 Zooming Sprites ]
|
||||
|
||||
The sprites are NOT tile based: the "tile" size can vary from
|
||||
8 to 64 (independently for width and height) with an 8 pixel
|
||||
granularity. The "tile" address is a multiple of 8x8 pixels.
|
||||
|
||||
Each sprite can be shrinked to ~1/4 or enlarged to ~32x following
|
||||
an exponential curve of sizes (with one zoom value for both width
|
||||
and height)
|
||||
|
||||
(legacy metro.cpp, currently contains Blazing Tornado overrides,
|
||||
to be moved into its own driver file!)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -95,647 +49,30 @@ TILEMAP_MAPPER_MEMBER(metro_state::tilemap_scan_gstrik2)
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Tilemaps: Tiles Set & Window
|
||||
|
||||
Each entry in the Tiles Set RAM uses 2 words to specify a starting
|
||||
tile code and a color code. This adds 16 consecutive tiles with
|
||||
that color code to the set of available tiles.
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.w fedc ---- ---- ----
|
||||
---- ba98 7654 ---- Color Code*
|
||||
---- ---- ---- 3210 Code High Bits
|
||||
|
||||
2.w Code Low Bits
|
||||
|
||||
* 00-ff, but on later chips supporting it, xf means 256 color tile and palette x
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
|
||||
Tilemaps: Rendering
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
// A 2048 x 2048 virtual tilemap
|
||||
#define BIG_NX (0x100)
|
||||
#define BIG_NY (0x100)
|
||||
|
||||
// A smaller 512 x 256 window defines the actual tilemap
|
||||
|
||||
#define WIN_NX (0x40)
|
||||
#define WIN_NY (0x20)
|
||||
|
||||
/* This looks up a single pixel in a tile, given the tile code.
|
||||
The Metro hardware has an indirection table, which is used here.
|
||||
Returns if to draw the pixel or not, pixel colour is placed in pix */
|
||||
inline uint8_t metro_state::get_tile_pix( uint16_t code, uint8_t x, uint8_t y, int big, uint16_t *pix )
|
||||
{
|
||||
int table_index;
|
||||
uint32_t tile;
|
||||
|
||||
// Use code as an index into the tiles set table
|
||||
table_index = ((code & 0x1ff0) >> 4) * 2;
|
||||
tile = (m_tiletable[table_index + 0] << 16) + m_tiletable[table_index + 1];
|
||||
|
||||
if (code & 0x8000) // Special: draw a tile of a single color (i.e. not from the gfx ROMs)
|
||||
{
|
||||
*pix = code & 0x0fff;
|
||||
|
||||
if ((*pix & 0xf) != 0xf)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if (((tile & 0x00f00000) == 0x00f00000) && (m_support_8bpp)) /* draw tile as 8bpp (e.g. balcube bg) */
|
||||
{
|
||||
gfx_element *gfx1 = m_gfxdecode->gfx(big?3:1);
|
||||
uint32_t tile2 = big ? ((tile & 0xfffff) + 8*(code & 0xf)) :
|
||||
((tile & 0xfffff) + 2*(code & 0xf));
|
||||
const uint8_t* data;
|
||||
uint8_t flipxy = (code & 0x6000) >> 13;
|
||||
|
||||
if (tile2 < gfx1->elements())
|
||||
data = gfx1->get_data(tile2);
|
||||
else
|
||||
{
|
||||
*pix = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (flipxy)
|
||||
{
|
||||
default:
|
||||
case 0x0: *pix = data[(y * (big?16:8)) + x]; break;
|
||||
case 0x1: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break;
|
||||
case 0x2: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break;
|
||||
case 0x3: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break;
|
||||
}
|
||||
|
||||
*pix |= ((tile & 0x0f000000) >> 24) * 0x100;
|
||||
|
||||
if ((*pix & 0xff) != 0xff)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx_element *gfx1 = m_gfxdecode->gfx(big?2:0);
|
||||
uint32_t tile2 = big ? ((tile & 0xfffff) + 4*(code & 0xf)) :
|
||||
((tile & 0xfffff) + (code & 0xf));
|
||||
const uint8_t* data;
|
||||
uint8_t flipxy = (code & 0x6000) >> 13;
|
||||
|
||||
if (tile2 < gfx1->elements())
|
||||
data = gfx1->get_data(tile2);
|
||||
else
|
||||
{
|
||||
*pix = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (flipxy)
|
||||
{
|
||||
default:
|
||||
case 0x0: *pix = data[(y * (big?16:8)) + x]; break;
|
||||
case 0x1: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break;
|
||||
case 0x2: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break;
|
||||
case 0x3: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break;
|
||||
}
|
||||
|
||||
*pix |= (((tile & 0x0ff00000) >> 20)) * 0x10;
|
||||
|
||||
if ((*pix & 0xf) != 0xf)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void metro_state::metro_vram_w( offs_t offset, uint16_t data, uint16_t mem_mask, int layer, uint16_t *vram )
|
||||
{
|
||||
COMBINE_DATA(&vram[offset]);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(metro_state::metro_vram_0_w){ metro_vram_w(offset, data, mem_mask, 0, m_vram_0); }
|
||||
WRITE16_MEMBER(metro_state::metro_vram_1_w){ metro_vram_w(offset, data, mem_mask, 1, m_vram_1); }
|
||||
WRITE16_MEMBER(metro_state::metro_vram_2_w){ metro_vram_w(offset, data, mem_mask, 2, m_vram_2); }
|
||||
|
||||
|
||||
|
||||
WRITE16_MEMBER(metro_state::metro_window_w)
|
||||
{
|
||||
COMBINE_DATA(&m_window[offset]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
|
||||
Video Init Routines
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
Sprites are not tile based, so we decode their graphics at runtime.
|
||||
*/
|
||||
|
||||
void metro_state::expand_gfx1()
|
||||
{
|
||||
uint8_t *base_gfx = memregion("gfx1")->base();
|
||||
uint32_t length = memregion("gfx1")->bytes() * 2;
|
||||
|
||||
m_expanded_gfx1 = std::make_unique<uint8_t[]>(length);
|
||||
|
||||
for (int i = 0; i < length; i += 2)
|
||||
{
|
||||
uint8_t src = base_gfx[i / 2];
|
||||
|
||||
m_expanded_gfx1[i + 0] = src & 0xf;
|
||||
m_expanded_gfx1[i + 1] = src >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(metro_state,metro_i4100)
|
||||
{
|
||||
expand_gfx1();
|
||||
|
||||
m_support_8bpp = 0;
|
||||
m_support_16x16 = 0;
|
||||
m_has_zoom = 0;
|
||||
|
||||
m_tilemap_scrolldx[0] = 0;
|
||||
m_tilemap_scrolldx[1] = 0;
|
||||
m_tilemap_scrolldx[2] = 0;
|
||||
|
||||
m_sprite_xoffs_dx = 0;
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(metro_state,metro_i4220)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(metro_i4100);
|
||||
|
||||
m_support_8bpp = 1; // balcube
|
||||
m_support_16x16 = 1; // vmetal
|
||||
}
|
||||
VIDEO_START_MEMBER(metro_state,metro_i4220_dx_tmap)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(metro_i4220);
|
||||
|
||||
m_tilemap_scrolldx[0] = -2;
|
||||
m_tilemap_scrolldx[1] = -2;
|
||||
m_tilemap_scrolldx[2] = -2;
|
||||
}
|
||||
VIDEO_START_MEMBER(metro_state,metro_i4220_dx_sprite)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(metro_i4220);
|
||||
|
||||
m_tilemap_scrolldx[0] = -16;
|
||||
m_tilemap_scrolldx[1] = -16;
|
||||
m_tilemap_scrolldx[2] = -16;
|
||||
m_sprite_xoffs_dx = 0;
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(metro_state,metro_i4300)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(metro_i4220);
|
||||
|
||||
// any additional feature?
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(metro_state,blzntrnd)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(metro_i4220);
|
||||
|
||||
m_has_zoom = 1;
|
||||
|
||||
m_k053936_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(metro_state::metro_k053936_get_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 256, 512);
|
||||
|
||||
m_tilemap_scrolldx[0] = 0;
|
||||
m_tilemap_scrolldx[1] = 0;
|
||||
m_tilemap_scrolldx[2] = 0;
|
||||
m_sprite_xoffs_dx = 0;
|
||||
|
||||
m_screen->register_screen_bitmap(m_vdp_bitmap);
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(metro_state,gstrik2)
|
||||
{
|
||||
VIDEO_START_CALL_MEMBER(metro_i4220);
|
||||
|
||||
m_has_zoom = 1;
|
||||
|
||||
m_k053936_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(metro_state::metro_k053936_gstrik2_get_tile_info),this), tilemap_mapper_delegate(FUNC(metro_state::tilemap_scan_gstrik2),this), 16, 16, 128, 256);
|
||||
|
||||
m_tilemap_scrolldx[0] = 0;
|
||||
m_tilemap_scrolldx[1] = -8;
|
||||
m_tilemap_scrolldx[2] = 0;
|
||||
m_sprite_xoffs_dx = 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Video Registers
|
||||
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.w Number Of Sprites To Draw
|
||||
2.w f--- ---- ---- ---- Disable Sprites Layer Priority
|
||||
-edc ---- ---- ----
|
||||
---- ba-- ---- ---- Sprites Masked Layer
|
||||
---- --98 ---- ---- Sprites Priority
|
||||
---- ---- 765- ----
|
||||
---- ---- ---4 3210 Sprites Masked Number
|
||||
4.w Sprites Y Offset
|
||||
6.w Sprites X Offset
|
||||
8.w Sprites Color Codes Start
|
||||
|
||||
-
|
||||
|
||||
10.w fedc ba98 76-- ----
|
||||
---- ---- --54 ---- Layer 2 Priority (3 backmost, 0 frontmost)
|
||||
---- ---- ---- 32-- Layer 1 Priority
|
||||
---- ---- ---- --10 Layer 0 Priority
|
||||
|
||||
12.w Backround Color
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Sprite Registers
|
||||
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.w Sprite Y center point
|
||||
2.w Sprite X center point
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
|
||||
Sprites Drawing
|
||||
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.w fedc b--- ---- ---- Priority (0 = Max)
|
||||
---- -a98 7654 3210 X
|
||||
|
||||
2.w fedc ba-- ---- ---- Zoom (Both X & Y)
|
||||
---- --98 7654 3210 Y
|
||||
|
||||
4.w f--- ---- ---- ---- Flip X
|
||||
-e-- ---- ---- ---- Flip Y
|
||||
--dc b--- ---- ---- Size X *
|
||||
---- -a98 ---- ---- Size Y *
|
||||
---- ---- 7654 ---- Color
|
||||
---- ---- ---- 3210 Code High Bits **
|
||||
|
||||
6.w Code Low Bits **
|
||||
|
||||
* 8 pixel increments
|
||||
** 8x8 pixel increments
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void metro_state::metro_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
|
||||
{
|
||||
uint8_t *base_gfx4 = m_expanded_gfx1.get();
|
||||
uint8_t *base_gfx8 = memregion("gfx1")->base();
|
||||
uint32_t gfx_size = memregion("gfx1")->bytes();
|
||||
|
||||
int max_x = (m_spriteregs[1]+1)*2;
|
||||
int max_y = (m_spriteregs[0]+1)*2;
|
||||
|
||||
int max_sprites = m_spriteram.bytes() / 8;
|
||||
int sprites = m_videoregs[0x00/2] % max_sprites;
|
||||
|
||||
int color_start = (m_videoregs[0x08/2] & 0x0f) << 4;
|
||||
|
||||
int i, j, pri;
|
||||
static const int primask[4] = { 0x0000, 0xff00, 0xff00 | 0xf0f0, 0xff00 | 0xf0f0 | 0xcccc };
|
||||
|
||||
uint16_t *src;
|
||||
int inc;
|
||||
|
||||
if (sprites == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 0x20; i++)
|
||||
{
|
||||
if (!(m_videoregs[0x02/2] & 0x8000))
|
||||
{
|
||||
src = m_spriteram + (sprites - 1) * (8 / 2);
|
||||
inc = -(8 / 2);
|
||||
} else {
|
||||
src = m_spriteram;
|
||||
inc = (8 / 2);
|
||||
}
|
||||
|
||||
for (j = 0; j < sprites; j++)
|
||||
{
|
||||
int x, y, attr, code, color, flipx, flipy, zoom, curr_pri, width, height;
|
||||
|
||||
// Exponential zoom table extracted from daitoride
|
||||
static const int zoomtable[0x40] =
|
||||
{ 0xAAC,0x800,0x668,0x554,0x494,0x400,0x390,0x334,
|
||||
0x2E8,0x2AC,0x278,0x248,0x224,0x200,0x1E0,0x1C8,
|
||||
0x1B0,0x198,0x188,0x174,0x164,0x154,0x148,0x13C,
|
||||
0x130,0x124,0x11C,0x110,0x108,0x100,0x0F8,0x0F0,
|
||||
0x0EC,0x0E4,0x0DC,0x0D8,0x0D4,0x0CC,0x0C8,0x0C4,
|
||||
0x0C0,0x0BC,0x0B8,0x0B4,0x0B0,0x0AC,0x0A8,0x0A4,
|
||||
0x0A0,0x09C,0x098,0x094,0x090,0x08C,0x088,0x080,
|
||||
0x078,0x070,0x068,0x060,0x058,0x050,0x048,0x040 };
|
||||
|
||||
x = src[0];
|
||||
curr_pri = (x & 0xf800) >> 11;
|
||||
|
||||
if ((curr_pri == 0x1f) || (curr_pri != i))
|
||||
{
|
||||
src += inc;
|
||||
continue;
|
||||
}
|
||||
|
||||
pri = (m_videoregs[0x02/2] & 0x0300) >> 8;
|
||||
|
||||
if (!(m_videoregs[0x02/2] & 0x8000))
|
||||
{
|
||||
if (curr_pri > (m_videoregs[0x02/2] & 0x1f))
|
||||
pri = (m_videoregs[0x02/2] & 0x0c00) >> 10;
|
||||
}
|
||||
|
||||
y = src[1];
|
||||
attr = src[2];
|
||||
code = src[3];
|
||||
|
||||
flipx = attr & 0x8000;
|
||||
flipy = attr & 0x4000;
|
||||
color = (attr & 0xf0) >> 4;
|
||||
|
||||
zoom = zoomtable[(y & 0xfc00) >> 10] << (16 - 8);
|
||||
|
||||
x = (x & 0x07ff) - m_sprite_xoffs;
|
||||
y = (y & 0x03ff) - m_sprite_yoffs;
|
||||
|
||||
width = (((attr >> 11) & 0x7) + 1) * 8;
|
||||
height = (((attr >> 8) & 0x7) + 1) * 8;
|
||||
|
||||
uint32_t gfxstart = (8 * 8 * 4 / 8) * (((attr & 0x000f) << 16) + code);
|
||||
|
||||
if (m_flip_screen)
|
||||
{
|
||||
flipx = !flipx; x = max_x - x - width;
|
||||
flipy = !flipy; y = max_y - y - height;
|
||||
}
|
||||
|
||||
if (m_support_8bpp && color == 0xf) /* 8bpp */
|
||||
{
|
||||
/* Bounds checking */
|
||||
if ((gfxstart + width * height - 1) >= gfx_size)
|
||||
continue;
|
||||
|
||||
gfx_element gfx(m_palette, base_gfx8 + gfxstart, width, height, width, m_palette->entries(), 0, 256);
|
||||
|
||||
gfx.prio_zoom_transpen(bitmap,cliprect,
|
||||
0,
|
||||
color_start >> 4,
|
||||
flipx, flipy,
|
||||
x, y,
|
||||
zoom, zoom,
|
||||
screen.priority(),primask[pri], 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bounds checking */
|
||||
if ((gfxstart + width / 2 * height - 1) >= gfx_size)
|
||||
continue;
|
||||
|
||||
gfx_element gfx(m_palette, base_gfx4 + 2 * gfxstart, width, height, width, m_palette->entries(),0, 16);
|
||||
|
||||
gfx.prio_zoom_transpen(bitmap,cliprect,
|
||||
0,
|
||||
color + color_start,
|
||||
flipx, flipy,
|
||||
x, y,
|
||||
zoom, zoom,
|
||||
screen.priority(),primask[pri], 15);
|
||||
}
|
||||
#if 0
|
||||
{ /* Display priority + zoom on each sprite */
|
||||
char buf[80];
|
||||
sprintf(buf, "%02X %02X", ((src[0] & 0xf800) >> 11) ^ 0x1f, ((src[1] & 0xfc00) >> 10));
|
||||
ui_draw_text(buf, x, y);
|
||||
}
|
||||
#endif
|
||||
src += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
|
||||
Screen Drawing
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
// Copy a 'window' from the large 2048x2048 (or 4096x4096 for 16x16 tiles) tilemap
|
||||
|
||||
void metro_state::draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode,
|
||||
int sx, int sy, int wx, int wy, int big, uint16_t *tilemapram, int layer )
|
||||
{
|
||||
int y;
|
||||
|
||||
bitmap_ind8 &priority_bitmap = m_screen->priority();
|
||||
|
||||
int width = big ? 4096 : 2048;
|
||||
int height = big ? 4096 : 2048;
|
||||
|
||||
int scrwidth = bitmap.width();
|
||||
int scrheight = bitmap.height();
|
||||
|
||||
int windowwidth = width >> 2;
|
||||
int windowheight = height >> 3;
|
||||
|
||||
sx += m_tilemap_scrolldx[layer] * (m_flip_screen ? 1 : -1);
|
||||
|
||||
for (y = 0; y < scrheight; y++)
|
||||
{
|
||||
int scrolly = (sy+y-wy)&(windowheight-1);
|
||||
int x;
|
||||
uint16_t *dst;
|
||||
uint8_t *priority_baseaddr;
|
||||
int srcline = (wy+scrolly)&(height-1);
|
||||
int srctilerow = srcline >> (big ? 4 : 3);
|
||||
|
||||
if (!m_flip_screen)
|
||||
{
|
||||
dst = &bitmap.pix16(y);
|
||||
priority_baseaddr = &priority_bitmap.pix8(y);
|
||||
|
||||
for (x = 0; x < scrwidth; x++)
|
||||
{
|
||||
int scrollx = (sx+x-wx)&(windowwidth-1);
|
||||
int srccol = (wx+scrollx)&(width-1);
|
||||
int srctilecol = srccol >> (big ? 4 : 3);
|
||||
int tileoffs = srctilecol + srctilerow * BIG_NX;
|
||||
|
||||
uint16_t dat = 0;
|
||||
|
||||
uint16_t tile = tilemapram[tileoffs];
|
||||
uint8_t draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat);
|
||||
|
||||
if (draw)
|
||||
{
|
||||
dst[x] = dat;
|
||||
priority_baseaddr[x] = (priority_baseaddr[x] & (pcode >> 8)) | pcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // flipped case
|
||||
{
|
||||
dst = &bitmap.pix16(scrheight-y-1);
|
||||
priority_baseaddr = &priority_bitmap.pix8(scrheight-y-1);
|
||||
|
||||
for (x = 0; x < scrwidth; x++)
|
||||
{
|
||||
int scrollx = (sx+x-wx)&(windowwidth-1);
|
||||
int srccol = (wx+scrollx)&(width-1);
|
||||
int srctilecol = srccol >> (big ? 4 : 3);
|
||||
int tileoffs = srctilecol + srctilerow * BIG_NX;
|
||||
|
||||
uint16_t dat = 0;
|
||||
|
||||
uint16_t tile = tilemapram[tileoffs];
|
||||
uint8_t draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat);
|
||||
|
||||
if (draw)
|
||||
{
|
||||
dst[scrwidth-x-1] = dat;
|
||||
priority_baseaddr[scrwidth-x-1] = (priority_baseaddr[scrwidth-x-1] & (pcode >> 8)) | pcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw all the layers that match the given priority
|
||||
|
||||
void metro_state::draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, int layers_ctrl )
|
||||
{
|
||||
uint16_t layers_pri = m_videoregs[0x10 / 2];
|
||||
int layer;
|
||||
|
||||
// Draw all the layers with priority == pri
|
||||
for (layer = 2; layer >= 0; layer--)
|
||||
{
|
||||
if (pri == ((layers_pri >> (layer * 2)) & 3))
|
||||
{
|
||||
// Scroll and Window values
|
||||
uint16_t sy = m_scroll[layer * 2 + 0]; uint16_t sx = m_scroll[layer * 2 + 1];
|
||||
uint16_t wy = m_window[layer * 2 + 0]; uint16_t wx = m_window[layer * 2 + 1];
|
||||
|
||||
if (BIT(layers_ctrl, layer)) // for debug
|
||||
{
|
||||
uint16_t *tilemapram = nullptr;
|
||||
|
||||
switch (layer)
|
||||
{
|
||||
case 0: tilemapram = m_vram_0; break;
|
||||
case 1: tilemapram = m_vram_1; break;
|
||||
case 2: tilemapram = m_vram_2; break;
|
||||
}
|
||||
|
||||
int big = m_support_16x16 && (*m_screenctrl & (0x0020 << layer));
|
||||
|
||||
draw_tilemap(screen, bitmap, cliprect, 0, 1 << (3 - pri), sx, sy, wx, wy, big, tilemapram, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t metro_state::screen_update_metro(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int pri, layers_ctrl = -1;
|
||||
uint16_t screenctrl = *m_screenctrl;
|
||||
|
||||
m_sprite_xoffs = m_videoregs[0x06 / 2] - (m_spriteregs[1]+1) + m_sprite_xoffs_dx;
|
||||
m_sprite_yoffs = m_videoregs[0x04 / 2] - (m_spriteregs[0]+1);
|
||||
|
||||
screen.priority().fill(0, cliprect);
|
||||
|
||||
// The background color is selected by a register
|
||||
bitmap.fill(m_videoregs[0x12/2] & 0x0fff, cliprect);
|
||||
|
||||
/* Screen Control Register:
|
||||
|
||||
f--- ---- ---- ---- ?
|
||||
-edc b--- ---- ----
|
||||
---- -a98 ---- ---- ? Leds (see gakusai attract)
|
||||
---- ---- 765- ---- 16x16 Tiles (Layer 2-1-0)
|
||||
---- ---- ---4 32--
|
||||
---- ---- ---- --1- Blank Screen
|
||||
---- ---- ---- ---0 Flip Screen */
|
||||
if (screenctrl & 2)
|
||||
return 0;
|
||||
|
||||
m_flip_screen = screenctrl & 1;
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
if (machine().input().code_pressed(KEYCODE_Z))
|
||||
{
|
||||
int msk = 0;
|
||||
if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1;
|
||||
if (machine().input().code_pressed(KEYCODE_W)) msk |= 2;
|
||||
if (machine().input().code_pressed(KEYCODE_E)) msk |= 4;
|
||||
if (machine().input().code_pressed(KEYCODE_A)) msk |= 8;
|
||||
if (msk != 0)
|
||||
{
|
||||
bitmap.fill(m_palette->black_pen(), cliprect);
|
||||
layers_ctrl &= msk;
|
||||
}
|
||||
|
||||
popmessage( "lyr: %x-%x-%x spr: %04x clr: %04x scr: %04x",
|
||||
(m_videoregs[0x10/2] & 0x30) >> 4, (m_videoregs[0x10/2] & 0xc) >> 2, m_videoregs[0x10/2] & 3,
|
||||
m_videoregs[0x02/2], m_videoregs[0x12/2],
|
||||
*m_screenctrl);
|
||||
m_screen->register_screen_bitmap(m_vdp_bitmap);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_has_zoom)
|
||||
{
|
||||
/* TODO: bit 5 of reg 7 is off when ROZ is supposed to be disabled
|
||||
* (Blazing Tornado title screen/character select/ending and Grand Striker 2 title/how to play transition)
|
||||
*/
|
||||
uint32_t metro_state::screen_update_psac_vdp2_mix(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* TODO: bit 5 of reg 7 is off when ROZ is supposed to be disabled
|
||||
* (Blazing Tornado title screen/character select/ending and Grand Striker 2 title/how to play transition)
|
||||
*/
|
||||
|
||||
m_k053936->zoom_draw(screen, bitmap, cliprect, m_k053936_tilemap, 0, 0, 1);
|
||||
}
|
||||
bitmap.fill(m_vdp2->get_background_pen(), cliprect);
|
||||
m_k053936->zoom_draw(screen, bitmap, cliprect, m_k053936_tilemap, 0, 0, 1);
|
||||
m_vdp2->screen_update(screen, m_vdp_bitmap, cliprect);
|
||||
copybitmap_trans(bitmap, m_vdp_bitmap, 0, 0, 0, 0, cliprect, m_vdp2->get_background_pen());
|
||||
|
||||
for (pri = 3; pri >= 0; pri--)
|
||||
draw_layers(screen, bitmap, cliprect, pri, layers_ctrl);
|
||||
|
||||
if (layers_ctrl & 0x08)
|
||||
metro_draw_sprites(screen, bitmap, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user