mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
zerohour: put driver into a single file
This commit is contained in:
parent
aa67ab477f
commit
c380aae3be
@ -87,7 +87,7 @@ public:
|
||||
protected:
|
||||
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
|
||||
void ladybug_palette(palette_device &palette) const;
|
||||
uint32_t screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
u32 screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void ladybug_map(address_map &map);
|
||||
|
||||
@ -117,14 +117,14 @@ protected:
|
||||
void decrypted_opcodes_map(address_map &map);
|
||||
|
||||
private:
|
||||
required_shared_ptr<uint8_t> m_decrypted_opcodes;
|
||||
required_shared_ptr<u8> m_decrypted_opcodes;
|
||||
};
|
||||
|
||||
void dorodon_state::init_dorodon()
|
||||
{
|
||||
/* decode the opcodes */
|
||||
uint8_t *rom = memregion("maincpu")->base();
|
||||
uint8_t *table = memregion("user1")->base();
|
||||
u8 *rom = memregion("maincpu")->base();
|
||||
u8 *table = memregion("user1")->base();
|
||||
|
||||
for (offs_t i = 0; i < 0x6000; i++)
|
||||
m_decrypted_opcodes[i] = table[rom[i]];
|
||||
@ -166,7 +166,7 @@ void ladybug_state::ladybug_palette(palette_device &palette) const
|
||||
2, resistances, gweights, 470, 0,
|
||||
2, resistances, bweights, 470, 0);
|
||||
|
||||
const uint8_t *color_prom = memregion("proms")->base();
|
||||
const u8 *color_prom = memregion("proms")->base();
|
||||
|
||||
// create a lookup table for the palette
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
@ -197,14 +197,14 @@ void ladybug_state::ladybug_palette(palette_device &palette) const
|
||||
// characters
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
|
||||
u8 const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
|
||||
palette.set_pen_indirect(i, ctabentry);
|
||||
}
|
||||
|
||||
// sprites
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
uint8_t ctabentry;
|
||||
u8 ctabentry;
|
||||
|
||||
ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
|
||||
palette.set_pen_indirect(i + 0x20, ctabentry);
|
||||
@ -214,19 +214,6 @@ void ladybug_state::ladybug_palette(palette_device &palette) const
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ladybug_state::screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(0, cliprect);
|
||||
m_video->draw(screen, bitmap, cliprect, flip_screen());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
I/O
|
||||
***************************************************************************/
|
||||
|
||||
WRITE_LINE_MEMBER(ladybug_state::flipscreen_w)
|
||||
{
|
||||
if (flip_screen() != state)
|
||||
@ -236,28 +223,11 @@ WRITE_LINE_MEMBER(ladybug_state::flipscreen_w)
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(ladybug_state::coin1_inserted)
|
||||
u32 ladybug_state::screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* left coin insertion causes an NMI */
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(ladybug_state::coin2_inserted)
|
||||
{
|
||||
/* right coin insertion causes an IRQ */
|
||||
if (newval)
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p1_control_r)
|
||||
{
|
||||
return m_p1_control->read();
|
||||
}
|
||||
|
||||
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p2_control_r)
|
||||
{
|
||||
// upright cabinet only uses a single set of controls */
|
||||
return ((m_port_dsw0->read() & 0x20) ? m_p2_control : m_p1_control)->read();
|
||||
bitmap.fill(0, cliprect);
|
||||
m_video->draw(screen, bitmap, cliprect, flip_screen());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -294,6 +264,31 @@ void dorodon_state::decrypted_opcodes_map(address_map &map)
|
||||
Input Ports
|
||||
***************************************************************************/
|
||||
|
||||
INPUT_CHANGED_MEMBER(ladybug_state::coin1_inserted)
|
||||
{
|
||||
/* left coin insertion causes an NMI */
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(ladybug_state::coin2_inserted)
|
||||
{
|
||||
/* right coin insertion causes an IRQ */
|
||||
if (newval)
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p1_control_r)
|
||||
{
|
||||
return m_p1_control->read();
|
||||
}
|
||||
|
||||
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p2_control_r)
|
||||
{
|
||||
// upright cabinet only uses a single set of controls */
|
||||
return ((m_port_dsw0->read() & 0x20) ? m_p2_control : m_p1_control)->read();
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START( ladybug )
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ladybug_state, ladybug_p1_control_r)
|
||||
|
@ -37,7 +37,7 @@ void ladybug_video_device::device_start()
|
||||
}
|
||||
|
||||
|
||||
void ladybug_video_device::bg_w(offs_t offset, uint8_t data)
|
||||
void ladybug_video_device::bg_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_bg_ram[offset & 0x07ff] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset & 0x03ff);
|
||||
|
@ -17,10 +17,10 @@ public:
|
||||
|
||||
template <typename T> void set_gfxdecode_tag(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
uint8_t spr_r(offs_t offset) { return m_spr_ram[offset & 0x03ff]; }
|
||||
void spr_w(offs_t offset, uint8_t data) { m_spr_ram[offset & 0x03ff] = data; }
|
||||
uint8_t bg_r(offs_t offset) { return m_bg_ram[offset & 0x07ff]; }
|
||||
void bg_w(offs_t offset, uint8_t data);
|
||||
u8 spr_r(offs_t offset) { return m_spr_ram[offset & 0x03ff]; }
|
||||
void spr_w(offs_t offset, u8 data) { m_spr_ram[offset & 0x03ff] = data; }
|
||||
u8 bg_r(offs_t offset) { return m_bg_ram[offset & 0x07ff]; }
|
||||
void bg_w(offs_t offset, u8 data);
|
||||
|
||||
void draw(screen_device &screen, bitmap_ind16 &bitmap, rectangle const &cliprect, bool flip);
|
||||
|
||||
|
@ -52,17 +52,17 @@ public:
|
||||
void mrsdyna(machine_config &config);
|
||||
|
||||
protected:
|
||||
uint8_t protection_r();
|
||||
void unk_0x28_w(uint8_t data);
|
||||
void unk_0x30_w(uint8_t data);
|
||||
void unk_0x38_w(uint8_t data);
|
||||
uint8_t rnd_r();
|
||||
virtual void io_w(uint8_t data);
|
||||
u8 protection_r();
|
||||
void unk_0x28_w(u8 data);
|
||||
void unk_0x30_w(u8 data);
|
||||
void unk_0x38_w(u8 data);
|
||||
u8 rnd_r();
|
||||
virtual void io_w(u8 data);
|
||||
void mrsdyna_palette(palette_device &palette) const;
|
||||
DECLARE_WRITE_LINE_MEMBER(update_stars);
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
virtual u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void cpu1_map(address_map &map);
|
||||
void cpu2_map(address_map &map);
|
||||
@ -74,10 +74,10 @@ protected:
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<ladybug_video_device> m_video;
|
||||
|
||||
uint8_t m_grid_color = 0;
|
||||
uint8_t m_0x28 = 0;
|
||||
uint8_t m_0x30 = 0;
|
||||
uint8_t m_0x38 = 0;
|
||||
u8 m_grid_color = 0;
|
||||
u8 m_0x28 = 0;
|
||||
u8 m_0x30 = 0;
|
||||
u8 m_0x38 = 0;
|
||||
};
|
||||
|
||||
// add stars from zerohour, uses grid layer
|
||||
@ -93,7 +93,7 @@ public:
|
||||
void sraider(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void io_w(uint8_t data) override;
|
||||
virtual void io_w(u8 data) override;
|
||||
void sraider_palette(palette_device &palette) const;
|
||||
DECLARE_WRITE_LINE_MEMBER(update_stars);
|
||||
TILE_GET_INFO_MEMBER(get_grid_tile_info);
|
||||
@ -101,10 +101,10 @@ protected:
|
||||
tilemap_t *m_grid_tilemap = nullptr;
|
||||
|
||||
virtual void video_start() override;
|
||||
virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
virtual u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
|
||||
private:
|
||||
required_shared_ptr<uint8_t> m_grid_data;
|
||||
required_shared_ptr<u8> m_grid_data;
|
||||
required_device<zerohour_stars_device> m_stars;
|
||||
};
|
||||
|
||||
@ -134,7 +134,7 @@ void mrsdyna_state::mrsdyna_palette(palette_device &palette) const
|
||||
2, resistances, gweights, 470, 0,
|
||||
2, resistances, bweights, 470, 0);
|
||||
|
||||
const uint8_t *color_prom = memregion("proms")->base();
|
||||
const u8 *color_prom = memregion("proms")->base();
|
||||
|
||||
// create a lookup table for the palette
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
@ -165,14 +165,14 @@ void mrsdyna_state::mrsdyna_palette(palette_device &palette) const
|
||||
// characters
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
|
||||
u8 const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
|
||||
palette.set_pen_indirect(i, ctabentry);
|
||||
}
|
||||
|
||||
// sprites
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
uint8_t ctabentry;
|
||||
u8 ctabentry;
|
||||
|
||||
ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
|
||||
palette.set_pen_indirect(i + 0x20, ctabentry);
|
||||
@ -214,6 +214,7 @@ void sraider_state::sraider_palette(palette_device &palette) const
|
||||
palette.set_pen_indirect(0x81, 0x40);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(sraider_state::get_grid_tile_info)
|
||||
{
|
||||
if (tile_index < 512)
|
||||
@ -243,7 +244,7 @@ WRITE_LINE_MEMBER(sraider_state::update_stars)
|
||||
m_stars->update_state();
|
||||
}
|
||||
|
||||
uint32_t mrsdyna_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
u32 mrsdyna_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// clear the bg bitmap
|
||||
bitmap.fill(0, cliprect);
|
||||
@ -254,7 +255,7 @@ uint32_t mrsdyna_state::screen_update(screen_device &screen, bitmap_ind16 &bitma
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sraider_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
u32 sraider_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// clear the bg bitmap
|
||||
bitmap.fill(0, cliprect);
|
||||
@ -285,7 +286,7 @@ uint32_t sraider_state::screen_update(screen_device &screen, bitmap_ind16 &bitma
|
||||
{
|
||||
if (m_grid_data[i] != 0)
|
||||
{
|
||||
uint8_t x = i;
|
||||
u8 x = i;
|
||||
int height = cliprect.max_y - cliprect.min_y + 1;
|
||||
|
||||
if (flip_screen())
|
||||
@ -307,7 +308,7 @@ uint32_t sraider_state::screen_update(screen_device &screen, bitmap_ind16 &bitma
|
||||
I/O
|
||||
***************************************************************************/
|
||||
|
||||
void mrsdyna_state::io_w(uint8_t data)
|
||||
void mrsdyna_state::io_w(u8 data)
|
||||
{
|
||||
// bit7 = flip
|
||||
// bit6 = grid red
|
||||
@ -325,7 +326,7 @@ void mrsdyna_state::io_w(uint8_t data)
|
||||
m_grid_color = data & 0x70;
|
||||
}
|
||||
|
||||
void sraider_state::io_w(uint8_t data)
|
||||
void sraider_state::io_w(u8 data)
|
||||
{
|
||||
mrsdyna_state::io_w(data);
|
||||
|
||||
@ -338,13 +339,13 @@ void sraider_state::io_w(uint8_t data)
|
||||
}
|
||||
|
||||
// documentation TBD - 556 dual timer
|
||||
uint8_t mrsdyna_state::rnd_r()
|
||||
u8 mrsdyna_state::rnd_r()
|
||||
{
|
||||
return machine().rand() & 3;
|
||||
}
|
||||
|
||||
// Protection - documentation TBD
|
||||
uint8_t mrsdyna_state::protection_r()
|
||||
u8 mrsdyna_state::protection_r()
|
||||
{
|
||||
// This must return X011111X or cpu #1 will hang
|
||||
// see code at rst $10
|
||||
@ -352,7 +353,7 @@ uint8_t mrsdyna_state::protection_r()
|
||||
}
|
||||
|
||||
// Unknown IO - documentation TBD
|
||||
void mrsdyna_state::unk_0x28_w(uint8_t data)
|
||||
void mrsdyna_state::unk_0x28_w(u8 data)
|
||||
{
|
||||
// These 8 bits are stored in the LS259 latch at A7,
|
||||
// and connected to all the select lines on 2 4066s at B7/C7
|
||||
@ -360,7 +361,7 @@ void mrsdyna_state::unk_0x28_w(uint8_t data)
|
||||
}
|
||||
|
||||
// documentation TBD
|
||||
void mrsdyna_state::unk_0x30_w(uint8_t data)
|
||||
void mrsdyna_state::unk_0x30_w(u8 data)
|
||||
{
|
||||
// bits 0-2 select 4051s at M7 and M8
|
||||
// bits 3-5 select 4051s at K7 and K8
|
||||
@ -368,7 +369,7 @@ void mrsdyna_state::unk_0x30_w(uint8_t data)
|
||||
}
|
||||
|
||||
// documentation TBD
|
||||
void mrsdyna_state::unk_0x38_w(uint8_t data)
|
||||
void mrsdyna_state::unk_0x38_w(u8 data)
|
||||
{
|
||||
// These 6 bits are stored in the LS174 latch at N8
|
||||
// bits 0-2 select 4051s at H7 and H8
|
||||
|
@ -27,18 +27,206 @@ TODO:
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "zerohour.h"
|
||||
#include "zerohour_stars.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/74259.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "video/resnet.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void zerohour_state::irqack_w(uint8_t data)
|
||||
class zerohour_state : public driver_device
|
||||
{
|
||||
m_maincpu->set_input_line(0, CLEAR_LINE);
|
||||
public:
|
||||
zerohour_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_videoram(*this, "videoram")
|
||||
, m_spriteram(*this, "spriteram")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_outlatch(*this, "outlatch%u", 0)
|
||||
, m_palette(*this, "palette")
|
||||
, m_gfxdecode(*this, "gfxdecode")
|
||||
, m_stars(*this, "stars")
|
||||
{ }
|
||||
|
||||
void base(machine_config &config);
|
||||
void zerohour(machine_config &config);
|
||||
void redclash(machine_config &config);
|
||||
|
||||
void init_zerohour();
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(left_coin_inserted);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(right_coin_inserted);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
DECLARE_WRITE_LINE_MEMBER(update_stars);
|
||||
void videoram_w(offs_t offset, u8 data);
|
||||
DECLARE_WRITE_LINE_MEMBER(gfxbank_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
|
||||
void irqack_w(u8 data) { m_maincpu->set_input_line(0, CLEAR_LINE); }
|
||||
void star_reset_w(u8 data);
|
||||
template <unsigned B> DECLARE_WRITE_LINE_MEMBER(star_w);
|
||||
void palette(palette_device &palette) const;
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void redclash_map(address_map &map);
|
||||
void zerohour_map(address_map &map);
|
||||
|
||||
required_shared_ptr<u8> m_videoram;
|
||||
required_shared_ptr<u8> m_spriteram;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device_array<ls259_device, 2> m_outlatch;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<zerohour_stars_device> m_stars;
|
||||
|
||||
tilemap_t *m_fg_tilemap = nullptr;
|
||||
int m_gfxbank = 0; // redclash only
|
||||
};
|
||||
|
||||
void zerohour_state::init_zerohour()
|
||||
{
|
||||
u8 const *const src = memregion("gfx2")->base();
|
||||
u8 *const dst = memregion("gfx3")->base();
|
||||
int const len = memregion("gfx3")->bytes();
|
||||
|
||||
/* rearrange the sprite graphics */
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
int const j = (i & ~0x003e) | ((i & 0x0e) << 2) | ((i & 0x30) >> 3);
|
||||
dst[i] = src[j];
|
||||
}
|
||||
}
|
||||
|
||||
void zerohour_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_gfxbank));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Video
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Convert the color PROMs into a more useable format.
|
||||
|
||||
I'm using the same palette conversion as Lady Bug, but the Zero Hour
|
||||
schematics show a different resistor network.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void zerohour_state::palette(palette_device &palette) const
|
||||
{
|
||||
const u8 *color_prom = memregion("proms")->base();
|
||||
|
||||
// create a lookup table for the palette
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int bit0, bit1;
|
||||
|
||||
// red component
|
||||
bit0 = BIT(color_prom[i], 0);
|
||||
bit1 = BIT(color_prom[i], 5);
|
||||
int const r = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
// green component
|
||||
bit0 = BIT(color_prom[i], 2);
|
||||
bit1 = BIT(color_prom[i], 6);
|
||||
int const g = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
// blue component
|
||||
bit0 = BIT(color_prom[i], 4);
|
||||
bit1 = BIT(color_prom[i], 7);
|
||||
int const b = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
// star colors
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int bit0, bit1;
|
||||
|
||||
// red component
|
||||
bit0 = BIT(i, 0);
|
||||
int const r = 0x97 * bit0;
|
||||
|
||||
// green component
|
||||
bit0 = BIT(i, 2);
|
||||
bit1 = BIT(i, 1);
|
||||
int const g = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
// blue component
|
||||
bit0 = BIT(i, 4);
|
||||
bit1 = BIT(i, 3);
|
||||
int const b = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
// color_prom now points to the beginning of the lookup table
|
||||
color_prom += 0x20;
|
||||
|
||||
// characters
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
u8 const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
|
||||
palette.set_pen_indirect(i, ctabentry);
|
||||
}
|
||||
|
||||
// sprites
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
u8 ctabentry;
|
||||
|
||||
ctabentry = bitswap<4>(color_prom[i], 0,1,2,3);
|
||||
palette.set_pen_indirect(i + 0x20, ctabentry);
|
||||
|
||||
ctabentry = bitswap<4>(color_prom[i], 4,5,6,7);
|
||||
palette.set_pen_indirect(i + 0x40, ctabentry);
|
||||
}
|
||||
|
||||
// stars
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
palette.set_pen_indirect(i + 0x60, i + 0x20);
|
||||
}
|
||||
|
||||
|
||||
void zerohour_state::videoram_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_videoram[offset] = data;
|
||||
m_fg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(zerohour_state::gfxbank_w)
|
||||
{
|
||||
if (m_gfxbank != state)
|
||||
{
|
||||
m_gfxbank = state;
|
||||
m_fg_tilemap->mark_all_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(zerohour_state::flipscreen_w)
|
||||
{
|
||||
flip_screen_set(state);
|
||||
}
|
||||
|
||||
template <unsigned B> WRITE_LINE_MEMBER(zerohour_state::star_w)
|
||||
@ -46,18 +234,164 @@ template <unsigned B> WRITE_LINE_MEMBER(zerohour_state::star_w)
|
||||
m_stars->set_speed(state ? 1 << B : 0, 1U << B);
|
||||
}
|
||||
|
||||
void zerohour_state::star_reset_w(u8 data)
|
||||
{
|
||||
m_stars->set_enable(true);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(zerohour_state::update_stars)
|
||||
{
|
||||
if (!state)
|
||||
m_stars->update_state();
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(zerohour_state::get_fg_tile_info)
|
||||
{
|
||||
int code = m_videoram[tile_index];
|
||||
int color = (m_videoram[tile_index] & 0x70) >> 4; // ??
|
||||
|
||||
tileinfo.set(0, code, color, 0);
|
||||
}
|
||||
|
||||
void zerohour_state::video_start()
|
||||
{
|
||||
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(zerohour_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_fg_tilemap->set_transparent_pen(0);
|
||||
}
|
||||
|
||||
void zerohour_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int offs = m_spriteram.bytes() - 0x20; offs >= 0; offs -= 0x20)
|
||||
{
|
||||
// find last valid sprite of current block
|
||||
int i = 0;
|
||||
while (i < 0x20 && m_spriteram[offs + i] != 0)
|
||||
i += 4;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
i -= 4;
|
||||
|
||||
if (m_spriteram[offs + i] & 0x80)
|
||||
{
|
||||
int color = bitswap<4>(m_spriteram[offs + i + 2], 5,2,1,0);
|
||||
int sx = m_spriteram[offs + i + 3];
|
||||
int sy = offs / 4 + (m_spriteram[offs + i] & 0x07) - 16;
|
||||
|
||||
switch ((m_spriteram[offs + i] & 0x18) >> 3)
|
||||
{
|
||||
case 3: /* 24x24 */
|
||||
{
|
||||
int code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
|
||||
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
/* wraparound */
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx - 256,sy,0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /* 16x16 */
|
||||
if (m_spriteram[offs + i] & 0x20) /* zero hour spaceships */
|
||||
{
|
||||
int code = ((m_spriteram[offs + i + 1] & 0xf8) >> 3) + ((m_gfxbank & 1) << 5);
|
||||
int bank = (m_spriteram[offs + i + 1] & 0x02) >> 1;
|
||||
|
||||
m_gfxdecode->gfx(4+bank)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
|
||||
|
||||
m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* 8x8 */
|
||||
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
|
||||
m_spriteram[offs + i + 1],// + 4 * (m_spriteram[offs + i + 2] & 0x10),
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
popmessage("unknown sprite size 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void zerohour_state::draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int offs = 0; offs < 0x20; offs++)
|
||||
{
|
||||
int sx = 8 * offs + 8;
|
||||
int sy = 0xff - m_videoram[offs + 0x20];
|
||||
|
||||
if (flip_screen())
|
||||
sx = 264 - sx;
|
||||
|
||||
int fine_x = m_videoram[offs] >> 3 & 7;
|
||||
sx -= fine_x;
|
||||
|
||||
for (int y = 0; y < 2; y++)
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
if (cliprect.contains(sx + x, sy - y))
|
||||
bitmap.pix(sy - y, sx + x) = 0x3f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
u32 zerohour_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(m_palette->black_pen(), cliprect);
|
||||
m_stars->draw(bitmap, cliprect);
|
||||
draw_bullets(bitmap, cliprect);
|
||||
draw_sprites(bitmap, cliprect);
|
||||
m_fg_tilemap->draw(screen, bitmap, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Address Maps
|
||||
***************************************************************************/
|
||||
|
||||
void zerohour_state::zerohour_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x2fff).rom();
|
||||
map(0x3000, 0x37ff).ram();
|
||||
map(0x3800, 0x3bff).ram().share(m_spriteram);
|
||||
map(0x4000, 0x43ff).ram().w(FUNC(zerohour_state::videoram_w)).share(m_videoram);
|
||||
map(0x4800, 0x4800).portr("IN0"); /* IN0 */
|
||||
map(0x4801, 0x4801).portr("IN1"); /* IN1 */
|
||||
map(0x4802, 0x4802).portr("DSW1"); /* DSW0 */
|
||||
map(0x4803, 0x4803).portr("DSW2"); /* DSW1 */
|
||||
map(0x5000, 0x5007).w("outlatch1", FUNC(ls259_device::write_d0)); /* to sound board */
|
||||
map(0x5800, 0x5807).w("outlatch2", FUNC(ls259_device::write_d0)); /* to sound board */
|
||||
map(0x4800, 0x4800).portr("IN0");
|
||||
map(0x4801, 0x4801).portr("IN1");
|
||||
map(0x4802, 0x4802).portr("DSW1");
|
||||
map(0x4803, 0x4803).portr("DSW2");
|
||||
map(0x5000, 0x5007).w(m_outlatch[0], FUNC(ls259_device::write_d0)); // to sound board
|
||||
map(0x5800, 0x5807).w(m_outlatch[1], FUNC(ls259_device::write_d0)); // to sound board
|
||||
map(0x7000, 0x7000).w(FUNC(zerohour_state::star_reset_w));
|
||||
map(0x7800, 0x7800).w(FUNC(zerohour_state::irqack_w));
|
||||
}
|
||||
@ -68,35 +402,37 @@ void zerohour_state::redclash_map(address_map &map)
|
||||
// map(0x3000, 0x3000).set_nopw();
|
||||
// map(0x3800, 0x3800).set_nopw();
|
||||
map(0x4000, 0x43ff).ram().w(FUNC(zerohour_state::videoram_w)).share(m_videoram);
|
||||
map(0x4800, 0x4800).portr("IN0"); /* IN0 */
|
||||
map(0x4801, 0x4801).portr("IN1"); /* IN1 */
|
||||
map(0x4802, 0x4802).portr("DSW1"); /* DSW0 */
|
||||
map(0x4803, 0x4803).portr("DSW2"); /* DSW1 */
|
||||
map(0x5000, 0x5007).w("outlatch1", FUNC(ls259_device::write_d0)); /* to sound board */
|
||||
map(0x5800, 0x5807).w("outlatch2", FUNC(ls259_device::write_d0)); /* to sound board */
|
||||
map(0x4800, 0x4800).portr("IN0");
|
||||
map(0x4801, 0x4801).portr("IN1");
|
||||
map(0x4802, 0x4802).portr("DSW1");
|
||||
map(0x4803, 0x4803).portr("DSW2");
|
||||
map(0x5000, 0x5007).w(m_outlatch[0], FUNC(ls259_device::write_d0)); // to sound board
|
||||
map(0x5800, 0x5807).w(m_outlatch[1], FUNC(ls259_device::write_d0)); // to sound board
|
||||
map(0x6000, 0x67ff).ram();
|
||||
map(0x6800, 0x6bff).ram().share(m_spriteram);
|
||||
map(0x7000, 0x7000).w(FUNC(zerohour_state::star_reset_w));
|
||||
map(0x7800, 0x7800).w(FUNC(zerohour_state::irqack_w));
|
||||
}
|
||||
|
||||
/*
|
||||
This game doesn't have VBlank interrupts.
|
||||
Interrupts are still used, but they are related to coin
|
||||
slots. Left slot generates an IRQ, Right slot a NMI.
|
||||
*/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Input Ports
|
||||
***************************************************************************/
|
||||
|
||||
INPUT_CHANGED_MEMBER( zerohour_state::left_coin_inserted )
|
||||
{
|
||||
if(newval)
|
||||
if (newval)
|
||||
m_maincpu->set_input_line(0, ASSERT_LINE);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER( zerohour_state::right_coin_inserted )
|
||||
{
|
||||
if(newval)
|
||||
if (newval)
|
||||
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START( zerohour )
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
|
||||
@ -115,20 +451,20 @@ static INPUT_PORTS_START( zerohour )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
/* Note that there are TWO VBlank inputs, one is active low, the other active */
|
||||
/* high. There are probably other differences in the hardware, but emulating */
|
||||
/* them this way is enough to get the game running. */
|
||||
// Note that there are TWO VBlank inputs, one is active low, the other active
|
||||
// high. There are probably other differences in the hardware, but emulating
|
||||
// them this way is enough to get the game running.
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
|
||||
|
||||
PORT_START("DSW1")
|
||||
PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "SW1:8" ) /* Switches 6-8 are not used */
|
||||
PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "SW1:8" ) // Switches 6-8 are not used
|
||||
PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "SW1:7" )
|
||||
PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW1:6" )
|
||||
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:5")
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Cocktail ) )
|
||||
PORT_DIPNAME( 0x30, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4,3") /* Also determines the default topscore, 0 for "No Bonus" */
|
||||
PORT_DIPNAME( 0x30, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4,3") // Also determines the default topscore, 0 for "No Bonus"
|
||||
PORT_DIPSETTING( 0x00, "No Bonus" )
|
||||
PORT_DIPSETTING( 0x30, "5000" )
|
||||
PORT_DIPSETTING( 0x20, "8000" )
|
||||
@ -145,7 +481,7 @@ static INPUT_PORTS_START( zerohour )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
|
||||
PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
|
||||
PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
|
||||
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) ) /* all other combinations give 1C_1C */
|
||||
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) ) // all other combinations give 1C_1C
|
||||
PORT_DIPSETTING( 0x09, DEF_STR( 2C_3C ) )
|
||||
PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
|
||||
PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
|
||||
@ -156,7 +492,7 @@ static INPUT_PORTS_START( zerohour )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
|
||||
PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
|
||||
PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
|
||||
PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) ) /* all other combinations give 1C_1C */
|
||||
PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) ) // all other combinations give 1C_1C
|
||||
PORT_DIPSETTING( 0x90, DEF_STR( 2C_3C ) )
|
||||
PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
|
||||
PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
|
||||
@ -164,9 +500,9 @@ static INPUT_PORTS_START( zerohour )
|
||||
PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
|
||||
|
||||
PORT_START("FAKE")
|
||||
/* The coin slots are not memory mapped. Coin Left causes a NMI, */
|
||||
/* Coin Right an IRQ. This fake input port is used by the interrupt */
|
||||
/* handler to be notified of coin insertions. */
|
||||
// The coin slots are not memory mapped. Coin Left causes a NMI,
|
||||
// Coin Right an IRQ. This fake input port is used by the interrupt
|
||||
// handler to be notified of coin insertions.
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, zerohour_state, left_coin_inserted, 0)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, zerohour_state, right_coin_inserted, 0)
|
||||
INPUT_PORTS_END
|
||||
@ -235,6 +571,12 @@ static INPUT_PORTS_START( redclash )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( 1C_9C ) )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
GFX Layouts
|
||||
***************************************************************************/
|
||||
|
||||
static const gfx_layout charlayout =
|
||||
{
|
||||
8,8,
|
||||
@ -300,26 +642,26 @@ static GFXDECODE_START( gfx_zerohour )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
void zerohour_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_gfxbank));
|
||||
}
|
||||
|
||||
void zerohour_state::zerohour(machine_config &config)
|
||||
/***************************************************************************
|
||||
Machine Configs
|
||||
***************************************************************************/
|
||||
|
||||
void zerohour_state::base(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, 4_MHz_XTAL); /* 4 MHz */
|
||||
// basic machine hardware
|
||||
Z80(config, m_maincpu, 4_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &zerohour_state::zerohour_map);
|
||||
|
||||
LS259(config, "outlatch1"); // C1 (CS10 decode)
|
||||
LS259(config, m_outlatch[0]); // C1 (CS10 decode)
|
||||
|
||||
ls259_device &outlatch2(LS259(config, "outlatch2")); // C2 (CS11 decode)
|
||||
outlatch2.q_out_cb<0>().set(FUNC(zerohour_state::star_w<0>));
|
||||
outlatch2.q_out_cb<5>().set(FUNC(zerohour_state::star_w<1>));
|
||||
outlatch2.q_out_cb<6>().set(FUNC(zerohour_state::star_w<2>));
|
||||
outlatch2.q_out_cb<7>().set(FUNC(zerohour_state::flipscreen_w));
|
||||
LS259(config, m_outlatch[1]); // C2 (CS11 decode)
|
||||
m_outlatch[1]->q_out_cb<0>().set(FUNC(zerohour_state::star_w<0>));
|
||||
m_outlatch[1]->q_out_cb<5>().set(FUNC(zerohour_state::star_w<1>));
|
||||
m_outlatch[1]->q_out_cb<6>().set(FUNC(zerohour_state::star_w<2>));
|
||||
m_outlatch[1]->q_out_cb<7>().set(FUNC(zerohour_state::flipscreen_w));
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(9.828_MHz_XTAL / 2, 312, 8, 248, 262, 32, 224);
|
||||
screen.set_screen_update(FUNC(zerohour_state::screen_update));
|
||||
@ -330,26 +672,27 @@ void zerohour_state::zerohour(machine_config &config)
|
||||
PALETTE(config, m_palette, FUNC(zerohour_state::palette), 4*8 + 4*16 + 32, 32 + 32);
|
||||
|
||||
ZEROHOUR_STARS(config, m_stars);
|
||||
|
||||
/* sound hardware */
|
||||
}
|
||||
|
||||
void zerohour_state::zerohour(machine_config &config)
|
||||
{
|
||||
base(config);
|
||||
|
||||
// sound hardware
|
||||
}
|
||||
|
||||
void zerohour_state::redclash(machine_config &config)
|
||||
{
|
||||
zerohour(config);
|
||||
base(config);
|
||||
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &zerohour_state::redclash_map);
|
||||
|
||||
subdevice<addressable_latch_device>("outlatch2")->q_out_cb<1>().set(FUNC(zerohour_state::gfxbank_w));
|
||||
m_outlatch[1]->q_out_cb<1>().set(FUNC(zerohour_state::gfxbank_w));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
ROM Definitions
|
||||
***************************************************************************/
|
||||
|
||||
ROM_START( zerohour )
|
||||
@ -534,26 +877,20 @@ ROM_START( redclashs )
|
||||
ROM_LOAD( "3.11e", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
|
||||
ROM_END
|
||||
|
||||
void zerohour_state::init_zerohour()
|
||||
{
|
||||
uint8_t const *const src = memregion("gfx2")->base();
|
||||
uint8_t *const dst = memregion("gfx3")->base();
|
||||
int const len = memregion("gfx3")->bytes();
|
||||
|
||||
/* rearrange the sprite graphics */
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
int const j = (i & ~0x003e) | ((i & 0x0e) << 2) | ((i & 0x30) >> 3);
|
||||
dst[i] = src[j];
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
GAME( 1980, zerohour, 0, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 1)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, zerohoura, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 2)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, zerohouri, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "bootleg (Inder SA)", "Zero Hour (Inder)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
GAME( 1981, redclash, 0, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko", "Red Clash", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, redclasht, redclash, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 1)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, redclashta, redclash, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 2)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, redclashs, redclash, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko (Suntronics license)", "Red Clash (Suntronics)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
/***************************************************************************
|
||||
Drivers
|
||||
***************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
|
||||
GAME( 1980, zerohour, 0, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 1)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, zerohoura, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 2)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, zerohouri, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "bootleg (Inder SA)", "Zero Hour (Inder)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
GAME( 1981, redclash, 0, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko", "Red Clash", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, redclasht, redclash, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 1)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, redclashta, redclash, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 2)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, redclashs, redclash, redclash, redclash, zerohour_state, init_zerohour, ROT270, "Kaneko (Suntronics license)", "Red Clash (Suntronics)", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,72 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:David Haywood
|
||||
/*************************************************************************
|
||||
|
||||
Zero Hour / Red Clash
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_INCLUDES_ZEROHOUR_H
|
||||
#define MAME_INCLUDES_ZEROHOUR_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "zerohour_stars.h"
|
||||
#include "emupal.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
class zerohour_state : public driver_device
|
||||
{
|
||||
public:
|
||||
zerohour_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_videoram(*this, "videoram")
|
||||
, m_spriteram(*this, "spriteram")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_palette(*this, "palette")
|
||||
, m_gfxdecode(*this, "gfxdecode")
|
||||
, m_stars(*this, "stars")
|
||||
{ }
|
||||
|
||||
void redclash(machine_config &config);
|
||||
void zerohour(machine_config &config);
|
||||
|
||||
void init_zerohour();
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(left_coin_inserted);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(right_coin_inserted);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
DECLARE_WRITE_LINE_MEMBER(update_stars);
|
||||
void videoram_w(offs_t offset, uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER(gfxbank_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
|
||||
void irqack_w(uint8_t data);
|
||||
void star_reset_w(uint8_t data);
|
||||
template <unsigned B> DECLARE_WRITE_LINE_MEMBER(star_w);
|
||||
void palette(palette_device &palette) const;
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void redclash_map(address_map &map);
|
||||
void zerohour_map(address_map &map);
|
||||
|
||||
required_shared_ptr<uint8_t> m_videoram;
|
||||
required_shared_ptr<uint8_t> m_spriteram;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<zerohour_stars_device> m_stars;
|
||||
|
||||
tilemap_t *m_fg_tilemap = nullptr;
|
||||
int m_gfxbank = 0; // redclash only
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_ZEROHOUR_H
|
@ -26,11 +26,11 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
u8 m_enable;
|
||||
u8 m_speed;
|
||||
u8 m_enable;
|
||||
u8 m_speed;
|
||||
u32 m_state;
|
||||
u16 m_offset;
|
||||
u8 m_count;
|
||||
u8 m_count;
|
||||
|
||||
u16 m_pal_offset;
|
||||
bool m_has_va_bit;
|
||||
|
@ -1,256 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:David Haywood
|
||||
/***************************************************************************
|
||||
|
||||
Functions to emulate the video hardware of the machine.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "zerohour.h"
|
||||
#include "video/resnet.h"
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Convert the color PROMs into a more useable format.
|
||||
|
||||
I'm using the same palette conversion as Lady Bug, but the Zero Hour
|
||||
schematics show a different resistor network.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void zerohour_state::palette(palette_device &palette) const
|
||||
{
|
||||
const uint8_t *color_prom = memregion("proms")->base();
|
||||
|
||||
// create a lookup table for the palette
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int bit0, bit1;
|
||||
|
||||
// red component
|
||||
bit0 = BIT(color_prom[i], 0);
|
||||
bit1 = BIT(color_prom[i], 5);
|
||||
int const r = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
// green component
|
||||
bit0 = BIT(color_prom[i], 2);
|
||||
bit1 = BIT(color_prom[i], 6);
|
||||
int const g = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
// blue component
|
||||
bit0 = BIT(color_prom[i], 4);
|
||||
bit1 = BIT(color_prom[i], 7);
|
||||
int const b = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
// star colors
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int bit0, bit1;
|
||||
|
||||
// red component
|
||||
bit0 = BIT(i, 0);
|
||||
int const r = 0x97 * bit0;
|
||||
|
||||
// green component
|
||||
bit0 = BIT(i, 2);
|
||||
bit1 = BIT(i, 1);
|
||||
int const g = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
// blue component
|
||||
bit0 = BIT(i, 4);
|
||||
bit1 = BIT(i, 3);
|
||||
int const b = 0x47 * bit0 + 0x97 * bit1;
|
||||
|
||||
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
// color_prom now points to the beginning of the lookup table
|
||||
color_prom += 0x20;
|
||||
|
||||
// characters
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
|
||||
palette.set_pen_indirect(i, ctabentry);
|
||||
}
|
||||
|
||||
// sprites
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
uint8_t ctabentry;
|
||||
|
||||
ctabentry = bitswap<4>(color_prom[i], 0,1,2,3);
|
||||
palette.set_pen_indirect(i + 0x20, ctabentry);
|
||||
|
||||
ctabentry = bitswap<4>(color_prom[i], 4,5,6,7);
|
||||
palette.set_pen_indirect(i + 0x40, ctabentry);
|
||||
}
|
||||
|
||||
// stars
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
palette.set_pen_indirect(i + 0x60, i + 0x20);
|
||||
}
|
||||
|
||||
|
||||
void zerohour_state::videoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_videoram[offset] = data;
|
||||
m_fg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(zerohour_state::gfxbank_w)
|
||||
{
|
||||
if (m_gfxbank != state)
|
||||
{
|
||||
m_gfxbank = state;
|
||||
m_fg_tilemap->mark_all_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(zerohour_state::flipscreen_w)
|
||||
{
|
||||
flip_screen_set(state);
|
||||
}
|
||||
|
||||
void zerohour_state::star_reset_w(uint8_t data)
|
||||
{
|
||||
m_stars->set_enable(true);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(zerohour_state::get_fg_tile_info)
|
||||
{
|
||||
int code = m_videoram[tile_index];
|
||||
int color = (m_videoram[tile_index] & 0x70) >> 4; // ??
|
||||
|
||||
tileinfo.set(0, code, color, 0);
|
||||
}
|
||||
|
||||
|
||||
void zerohour_state::video_start()
|
||||
{
|
||||
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(zerohour_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_fg_tilemap->set_transparent_pen(0);
|
||||
}
|
||||
|
||||
void zerohour_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int offs = m_spriteram.bytes() - 0x20; offs >= 0; offs -= 0x20)
|
||||
{
|
||||
// find last valid sprite of current block
|
||||
int i = 0;
|
||||
while (i < 0x20 && m_spriteram[offs + i] != 0)
|
||||
i += 4;
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
i -= 4;
|
||||
|
||||
if (m_spriteram[offs + i] & 0x80)
|
||||
{
|
||||
int color = bitswap<4>(m_spriteram[offs + i + 2], 5,2,1,0);
|
||||
int sx = m_spriteram[offs + i + 3];
|
||||
int sy = offs / 4 + (m_spriteram[offs + i] & 0x07) - 16;
|
||||
|
||||
switch ((m_spriteram[offs + i] & 0x18) >> 3)
|
||||
{
|
||||
case 3: /* 24x24 */
|
||||
{
|
||||
int code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
|
||||
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
/* wraparound */
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx - 256,sy,0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /* 16x16 */
|
||||
if (m_spriteram[offs + i] & 0x20) /* zero hour spaceships */
|
||||
{
|
||||
int code = ((m_spriteram[offs + i + 1] & 0xf8) >> 3) + ((m_gfxbank & 1) << 5);
|
||||
int bank = (m_spriteram[offs + i + 1] & 0x02) >> 1;
|
||||
|
||||
m_gfxdecode->gfx(4+bank)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
|
||||
|
||||
m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
|
||||
code,
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* 8x8 */
|
||||
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
|
||||
m_spriteram[offs + i + 1],// + 4 * (m_spriteram[offs + i + 2] & 0x10),
|
||||
color,
|
||||
0,0,
|
||||
sx,sy,0);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
popmessage("unknown sprite size 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void zerohour_state::draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int offs = 0; offs < 0x20; offs++)
|
||||
{
|
||||
int sx = 8 * offs + 8;
|
||||
int sy = 0xff - m_videoram[offs + 0x20];
|
||||
|
||||
if (flip_screen())
|
||||
sx = 264 - sx;
|
||||
|
||||
int fine_x = m_videoram[offs] >> 3 & 7;
|
||||
sx -= fine_x;
|
||||
|
||||
for (int y = 0; y < 2; y++)
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
if (cliprect.contains(sx + x, sy - y))
|
||||
bitmap.pix(sy - y, sx + x) = 0x3f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(zerohour_state::update_stars)
|
||||
{
|
||||
if (!state)
|
||||
m_stars->update_state();
|
||||
}
|
||||
|
||||
uint32_t zerohour_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(m_palette->black_pen(), cliprect);
|
||||
m_stars->draw(bitmap, cliprect);
|
||||
draw_bullets(bitmap, cliprect);
|
||||
draw_sprites(bitmap, cliprect);
|
||||
m_fg_tilemap->draw(screen, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user