mirror of
https://github.com/holub/mame
synced 2025-06-05 04:16:28 +03:00
flower.cpp: Replace hardcoded tags to region pointers, Fix some sound/cocktail mode behaviors (#8944)
* flower.cpp: Replace hardcoded tags to region pointers, Fix some sound/cocktail mode behaviors - Use tilemap_t for text layer - Add hardware notes - Add notes for unknown sound register writes - Add sound io register value for debug purpose - Fix initializing behavior - Use shorter/correct type values, Fix spacings - Fix GFX ROM naming * audio/flower.cpp: Reduce unnecessary values/pointers - Use STRUCT_MEMBER for save values
This commit is contained in:
parent
edcfe24353
commit
7eac6c8acc
@ -9,6 +9,8 @@
|
||||
TODO:
|
||||
- several unknown registers (effects and unknown register tied to repeat port);
|
||||
- repeat certainly needs a cutoff, which is unknown about how it works;
|
||||
- keyon/off behavior is not verified
|
||||
- PCM output is incorrect/unverified
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -42,14 +44,15 @@ void flower_sound_device::regs_map(address_map &map)
|
||||
// flower_sound_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
flower_sound_device::flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
flower_sound_device::flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, FLOWER_CUSTOM, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this),
|
||||
device_memory_interface(mconfig, *this),
|
||||
m_io_space_config("io", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(flower_sound_device::regs_map), this)),
|
||||
m_stream(nullptr),
|
||||
m_mixer_lookup(nullptr),
|
||||
m_last_channel(nullptr)
|
||||
m_sample_rom(*this, "samples"),
|
||||
m_volume_rom(*this, "soundvol")
|
||||
{
|
||||
}
|
||||
|
||||
@ -66,25 +69,18 @@ void flower_sound_device::device_start()
|
||||
m_mixer_buffer.resize(clock()/50);
|
||||
make_mixer_table(MAX_VOICES, defgain);
|
||||
|
||||
m_last_channel = m_channel_list + MAX_VOICES;
|
||||
save_item(STRUCT_MEMBER(m_channel_list, start_nibbles));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, raw_frequency));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, start_address));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, position));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, frequency));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, volume));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, volume_bank));
|
||||
//save_item(STRUCT_MEMBER(m_channel_list, effect));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, enable));
|
||||
save_item(STRUCT_MEMBER(m_channel_list, repeat));
|
||||
|
||||
m_sample_rom = machine().root_device().memregion("samples")->base();
|
||||
m_volume_rom = machine().root_device().memregion("soundvol")->base();
|
||||
|
||||
for (int i = 0; i < MAX_VOICES; i++)
|
||||
{
|
||||
save_item(NAME(m_channel_list[i].start_address), i);
|
||||
save_item(NAME(m_channel_list[i].position), i);
|
||||
save_item(NAME(m_channel_list[i].frequency), i);
|
||||
save_item(NAME(m_channel_list[i].volume), i);
|
||||
save_item(NAME(m_channel_list[i].volume_bank), i);
|
||||
save_item(NAME(m_channel_list[i].effect), i);
|
||||
save_item(NAME(m_channel_list[i].enable), i);
|
||||
save_item(NAME(m_channel_list[i].repeat), i);
|
||||
|
||||
// assign a channel number (debugger aid)
|
||||
m_channel_list[i].channel_number = i;
|
||||
}
|
||||
save_item(NAME(m_io_regs));
|
||||
}
|
||||
|
||||
|
||||
@ -115,13 +111,13 @@ void flower_sound_device::make_mixer_table(int voices, int gain)
|
||||
|
||||
void flower_sound_device::device_reset()
|
||||
{
|
||||
for (fl_sound_channel *voice = m_channel_list; voice < m_last_channel; voice++)
|
||||
for (auto & voice : m_channel_list)
|
||||
{
|
||||
voice->start_address = 0;
|
||||
voice->position = 0;
|
||||
voice->volume = 0;
|
||||
voice->enable = false;
|
||||
voice->repeat = false;
|
||||
voice.start_address = 0;
|
||||
voice.position = 0;
|
||||
voice.volume = 0;
|
||||
voice.enable = false;
|
||||
voice.repeat = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,45 +125,45 @@ void flower_sound_device::sound_stream_update(sound_stream &stream, std::vector<
|
||||
{
|
||||
auto &buffer = outputs[0];
|
||||
short *mix;
|
||||
uint8_t raw_sample;
|
||||
u8 raw_sample;
|
||||
|
||||
std::fill_n(&m_mixer_buffer[0], buffer.samples(), 0);
|
||||
|
||||
for (fl_sound_channel *voice = m_channel_list; voice < m_last_channel; voice++)
|
||||
for (auto & voice : m_channel_list)
|
||||
{
|
||||
int ch_volume = voice->volume;
|
||||
int ch_frequency = voice->frequency;
|
||||
int ch_volume = voice.volume;
|
||||
int ch_frequency = voice.frequency;
|
||||
|
||||
if (voice->enable == false)
|
||||
if (!voice.enable)
|
||||
continue;
|
||||
|
||||
mix = &m_mixer_buffer[0];
|
||||
|
||||
for (int i = 0; i < buffer.samples(); i++)
|
||||
{
|
||||
if (voice->repeat == true)
|
||||
if (voice.repeat)
|
||||
{
|
||||
raw_sample = m_sample_rom[((voice->start_address >> 7) & 0x7e00) | ((voice->position >> 7) & 0x1ff)];
|
||||
// guess: cut off after a number of repetitions
|
||||
if ((voice->position >> 7) & 0x20000)
|
||||
raw_sample = m_sample_rom[((voice.start_address >> 7) & 0x7e00) | ((voice.position >> 7) & 0x1ff)];
|
||||
// guess: key on/off bit is lowest bit of volume bank register?
|
||||
if ((voice.volume_bank & 0x10) != 0x10)
|
||||
{
|
||||
voice->enable = false;
|
||||
voice.enable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
raw_sample = m_sample_rom[((voice->start_address + voice->position) >> 7) & 0x7fff];
|
||||
raw_sample = m_sample_rom[((voice.start_address + voice.position) >> 7) & 0x7fff];
|
||||
if (raw_sample == 0xff)
|
||||
{
|
||||
voice->enable = false;
|
||||
voice.enable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ch_volume |= voice->volume_bank;
|
||||
ch_volume |= voice.volume_bank;
|
||||
|
||||
*mix++ += m_volume_rom[(ch_volume << 8 | raw_sample) & 0x3fff] - 0x80;
|
||||
voice->position += ch_frequency;
|
||||
voice.position += ch_frequency;
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,80 +189,83 @@ device_memory_interface::space_config_vector flower_sound_device::memory_space_c
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
void flower_sound_device::lower_write(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::lower_write(offs_t offset, u8 data)
|
||||
{
|
||||
m_stream->update();
|
||||
m_io_regs[offset] = data;
|
||||
m_iospace->write_byte(offset,data);
|
||||
}
|
||||
|
||||
void flower_sound_device::upper_write(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::upper_write(offs_t offset, u8 data)
|
||||
{
|
||||
m_stream->update();
|
||||
m_io_regs[offset|0x40] = data;
|
||||
m_iospace->write_byte(offset|0x40,data);
|
||||
}
|
||||
|
||||
void flower_sound_device::frequency_w(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::frequency_w(offs_t offset, u8 data)
|
||||
{
|
||||
uint8_t ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel *voice;
|
||||
u8 ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel &voice = m_channel_list[ch];
|
||||
|
||||
voice = &m_channel_list[ch];
|
||||
// Low nibbles: part of frequency
|
||||
// High nibbles: unknown
|
||||
voice.raw_frequency[offset & 3] = data;
|
||||
|
||||
voice->raw_frequency[offset & 3] = data & 0xf;
|
||||
|
||||
voice->frequency = voice->raw_frequency[2] << 12;
|
||||
voice->frequency|= voice->raw_frequency[3] << 8;
|
||||
voice->frequency|= voice->raw_frequency[0] << 4;
|
||||
voice->frequency|= voice->raw_frequency[1] << 0;
|
||||
voice.frequency = (voice.raw_frequency[2] & 0xf) << 12;
|
||||
voice.frequency|= (voice.raw_frequency[3] & 0xf) << 8;
|
||||
voice.frequency|= (voice.raw_frequency[0] & 0xf) << 4;
|
||||
voice.frequency|= (voice.raw_frequency[1] & 0xf) << 0;
|
||||
}
|
||||
|
||||
void flower_sound_device::repeat_w(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::repeat_w(offs_t offset, u8 data)
|
||||
{
|
||||
uint8_t ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel *voice;
|
||||
u8 ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel &voice = m_channel_list[ch];
|
||||
|
||||
voice = &m_channel_list[ch];
|
||||
voice->repeat = BIT(data,4);
|
||||
voice.repeat = BIT(data, 4); // Bit 4: Repeat flag?
|
||||
}
|
||||
|
||||
void flower_sound_device::unk_w(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::unk_w(offs_t offset, u8 data)
|
||||
{
|
||||
// same as above?
|
||||
}
|
||||
|
||||
void flower_sound_device::volume_w(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::volume_w(offs_t offset, u8 data)
|
||||
{
|
||||
uint8_t ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel *voice;
|
||||
u8 ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel &voice = m_channel_list[ch];
|
||||
|
||||
voice = &m_channel_list[ch];
|
||||
voice->volume = data >> 4;
|
||||
// Low nibbles: unknown
|
||||
// High nibbles: volume
|
||||
voice.volume = data >> 4;
|
||||
}
|
||||
|
||||
void flower_sound_device::start_address_w(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::start_address_w(offs_t offset, u8 data)
|
||||
{
|
||||
uint8_t ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel *voice;
|
||||
u8 ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel &voice = m_channel_list[ch];
|
||||
|
||||
voice = &m_channel_list[ch];
|
||||
voice->start_nibbles[offset & 7] = data & 0xf;
|
||||
// Low nibbles: part of start address
|
||||
// High nibbles: unknown
|
||||
voice.start_nibbles[offset & 7] = data;
|
||||
/*
|
||||
if ((offset & 7) == 4)
|
||||
voice->effect = data >> 4;
|
||||
voice.effect = data >> 4;
|
||||
*/
|
||||
}
|
||||
|
||||
void flower_sound_device::sample_trigger_w(offs_t offset, uint8_t data)
|
||||
void flower_sound_device::sample_trigger_w(offs_t offset, u8 data)
|
||||
{
|
||||
uint8_t ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel *voice;
|
||||
u8 ch = (offset >> 3) & 0x7;
|
||||
fl_sound_channel &voice = m_channel_list[ch];
|
||||
|
||||
voice = &m_channel_list[ch];
|
||||
|
||||
voice->enable = true;
|
||||
voice->volume_bank = (data & 3) << 4;
|
||||
voice->start_address = 0;
|
||||
voice->position = 0;
|
||||
voice.enable = true; // BIT(data, 0);
|
||||
voice.volume_bank = (data & 3) << 4; // Bit 0: Keyon/off?, Bit 1: PCM/Wavetable mode select?
|
||||
voice.start_address = 0;
|
||||
voice.position = 0;
|
||||
for (int i = 5; i >= 0; i--)
|
||||
{
|
||||
voice->start_address = (voice->start_address << 4) | voice->start_nibbles[i];
|
||||
voice.start_address = (voice.start_address << 4) | (voice.start_nibbles[i] & 0xf);
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,11 @@ class flower_sound_device : public device_t,
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
// I/O operations
|
||||
void lower_write(offs_t offset, uint8_t data);
|
||||
void upper_write(offs_t offset, uint8_t data);
|
||||
void lower_write(offs_t offset, u8 data);
|
||||
void upper_write(offs_t offset, u8 data);
|
||||
// virtual void lower_map(address_map &map);
|
||||
// virtual void upper_map(address_map &map);
|
||||
|
||||
@ -50,40 +50,40 @@ private:
|
||||
static constexpr unsigned MAX_VOICES = 8;
|
||||
static constexpr int defgain = 48;
|
||||
|
||||
std::vector<int16_t> m_mixer_table;
|
||||
int16_t *m_mixer_lookup;
|
||||
u8 m_io_regs[0x80] = {0}; // for debug purpose
|
||||
|
||||
std::vector<s16> m_mixer_table;
|
||||
s16 *m_mixer_lookup;
|
||||
std::vector<short> m_mixer_buffer;
|
||||
|
||||
struct fl_sound_channel
|
||||
{
|
||||
uint8_t start_nibbles[6];
|
||||
uint8_t raw_frequency[4];
|
||||
uint32_t start_address;
|
||||
uint32_t position;
|
||||
uint16_t frequency;
|
||||
uint8_t volume;
|
||||
uint8_t volume_bank;
|
||||
uint8_t effect;
|
||||
bool enable;
|
||||
bool repeat;
|
||||
int channel_number;
|
||||
u8 start_nibbles[6] = {0};
|
||||
u8 raw_frequency[4] = {0};
|
||||
u32 start_address = 0;
|
||||
u32 position = 0;
|
||||
u16 frequency = 0;
|
||||
u8 volume = 0;
|
||||
u8 volume_bank = 0;
|
||||
//u8 effect = 0;
|
||||
bool enable = false;
|
||||
bool repeat = false;
|
||||
};
|
||||
|
||||
/* data about the sound system */
|
||||
fl_sound_channel m_channel_list[MAX_VOICES];
|
||||
fl_sound_channel *m_last_channel;
|
||||
|
||||
void make_mixer_table(int voices, int gain);
|
||||
|
||||
const uint8_t *m_sample_rom;
|
||||
const uint8_t *m_volume_rom;
|
||||
required_region_ptr<u8> m_sample_rom;
|
||||
required_region_ptr<u8> m_volume_rom;
|
||||
|
||||
void frequency_w(offs_t offset, uint8_t data);
|
||||
void repeat_w(offs_t offset, uint8_t data);
|
||||
void unk_w(offs_t offset, uint8_t data);
|
||||
void volume_w(offs_t offset, uint8_t data);
|
||||
void start_address_w(offs_t offset, uint8_t data);
|
||||
void sample_trigger_w(offs_t offset, uint8_t data);
|
||||
void frequency_w(offs_t offset, u8 data);
|
||||
void repeat_w(offs_t offset, u8 data);
|
||||
void unk_w(offs_t offset, u8 data);
|
||||
void volume_w(offs_t offset, u8 data);
|
||||
void start_address_w(offs_t offset, u8 data);
|
||||
void sample_trigger_w(offs_t offset, u8 data);
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,6 +12,11 @@
|
||||
galaxy, planet ship 3rd boss, 2nd boss);
|
||||
- sound chips (similar to Namco custom chips?)
|
||||
|
||||
Video reference:
|
||||
https://youtu.be/ycbJMG09UZ0
|
||||
https://youtu.be/NolazjlEiAY
|
||||
https://youtu.be/8JOPTCWu67g
|
||||
|
||||
===============================================================================
|
||||
|
||||
Flower (c)1986 Komax (USA license)
|
||||
@ -114,17 +119,20 @@ public:
|
||||
DECLARE_INPUT_CHANGED_MEMBER(coin_inserted);
|
||||
|
||||
private:
|
||||
void flipscreen_w(uint8_t data);
|
||||
void coin_counter_w(uint8_t data);
|
||||
void sound_command_w(uint8_t data);
|
||||
void audio_nmi_mask_w(uint8_t data);
|
||||
void bgvram_w(offs_t offset, uint8_t data);
|
||||
void fgvram_w(offs_t offset, uint8_t data);
|
||||
void flipscreen_w(u8 data);
|
||||
void coin_counter_w(u8 data);
|
||||
void sound_command_w(u8 data);
|
||||
void audio_nmi_mask_w(u8 data);
|
||||
void bgvram_w(offs_t offset, u8 data);
|
||||
void fgvram_w(offs_t offset, u8 data);
|
||||
void txvram_w(offs_t offset, u8 data);
|
||||
INTERRUPT_GEN_MEMBER(master_vblank_irq);
|
||||
INTERRUPT_GEN_MEMBER(slave_vblank_irq);
|
||||
TILE_GET_INFO_MEMBER(get_tx_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TILEMAP_MAPPER_MEMBER(tilemap_scan);
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void audio_map(address_map &map);
|
||||
void shared_map(address_map &map);
|
||||
@ -141,86 +149,74 @@ private:
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_shared_ptr<uint8_t> m_txvram;
|
||||
required_shared_ptr<uint8_t> m_bgvram;
|
||||
required_shared_ptr<uint8_t> m_fgvram;
|
||||
required_shared_ptr<uint8_t> m_workram;
|
||||
required_shared_ptr<uint8_t> m_bgscroll;
|
||||
required_shared_ptr<uint8_t> m_fgscroll;
|
||||
required_shared_ptr<u8> m_txvram;
|
||||
required_shared_ptr<u8> m_bgvram;
|
||||
required_shared_ptr<u8> m_fgvram;
|
||||
required_shared_ptr<u8> m_workram;
|
||||
required_shared_ptr<u8> m_bgscroll;
|
||||
required_shared_ptr<u8> m_fgscroll;
|
||||
required_device<generic_latch_8_device> m_soundlatch;
|
||||
bitmap_ind16 m_temp_bitmap;
|
||||
|
||||
void draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &cliprect);
|
||||
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
|
||||
|
||||
bool m_audio_nmi_enable;
|
||||
bool m_flip_screen;
|
||||
bool m_audio_nmi_enable = false;
|
||||
bool m_flip_screen = false;
|
||||
tilemap_t *m_bg_tilemap;
|
||||
tilemap_t *m_fg_tilemap;
|
||||
tilemap_t *m_tx_tilemap;
|
||||
};
|
||||
|
||||
TILE_GET_INFO_MEMBER(flower_state::get_tx_tile_info)
|
||||
{
|
||||
const u32 code = m_txvram[tile_index];
|
||||
const u32 color = (m_txvram[tile_index + 0x400] & 0xfc) >> 2;
|
||||
|
||||
tileinfo.set(0, code, color, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(flower_state::get_bg_tile_info)
|
||||
{
|
||||
int code = m_bgvram[tile_index];
|
||||
int color = (m_bgvram[tile_index+0x100] & 0xf0) >> 4;
|
||||
const u32 code = m_bgvram[tile_index];
|
||||
const u32 color = (m_bgvram[tile_index + 0x100] & 0xf0) >> 4;
|
||||
|
||||
tileinfo.set(1, code, color, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(flower_state::get_fg_tile_info)
|
||||
{
|
||||
int code = m_fgvram[tile_index];
|
||||
int color = (m_fgvram[tile_index+0x100] & 0xf0) >> 4;
|
||||
const u32 code = m_fgvram[tile_index];
|
||||
const u32 color = (m_fgvram[tile_index + 0x100] & 0xf0) >> 4;
|
||||
|
||||
tileinfo.set(1, code, color, 0);
|
||||
}
|
||||
|
||||
// convert from 32x32 to 36x28, similar as Namco hardware
|
||||
TILEMAP_MAPPER_MEMBER(flower_state::tilemap_scan)
|
||||
{
|
||||
row += 2;
|
||||
col -= 2;
|
||||
if (col & 0x20)
|
||||
return ((col & 0x1f) << 5) + row;
|
||||
else
|
||||
return (row << 5) + col;
|
||||
}
|
||||
|
||||
void flower_state::video_start()
|
||||
{
|
||||
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16);
|
||||
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16);
|
||||
m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(flower_state::get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(flower_state::tilemap_scan)), 8, 8, 36, 28);
|
||||
|
||||
m_screen->register_screen_bitmap(m_temp_bitmap);
|
||||
m_fg_tilemap->set_transparent_pen(15);
|
||||
m_tx_tilemap->set_transparent_pen(3);
|
||||
|
||||
save_item(NAME(m_flip_screen));
|
||||
|
||||
m_bg_tilemap->set_scrolldx(16, 0);
|
||||
m_fg_tilemap->set_scrolldx(16, 0);
|
||||
}
|
||||
|
||||
void flower_state::draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &cliprect)
|
||||
{
|
||||
gfx_element *gfx_0 = m_gfxdecode->gfx(0);
|
||||
int count;
|
||||
|
||||
for (count=0;count<32*32;count++)
|
||||
{
|
||||
int x = count % 32;
|
||||
int y = count / 32;
|
||||
|
||||
uint8_t tile = m_txvram[count];
|
||||
uint8_t attr = m_txvram[count+0x400];
|
||||
|
||||
if(attr & 0x03) // debug
|
||||
attr = machine().rand() & 0xfc;
|
||||
|
||||
gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+16,y*8,3);
|
||||
}
|
||||
|
||||
for (count=0;count<0x40;count++)
|
||||
{
|
||||
int x = count / 32;
|
||||
int y = count % 32;
|
||||
|
||||
uint8_t tile = m_txvram[count];
|
||||
uint8_t attr = m_txvram[count+0x400];
|
||||
|
||||
if(attr & 0x03) // debug
|
||||
attr = machine().rand() & 0xfc;
|
||||
|
||||
gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+256+16,y*8,3);
|
||||
}
|
||||
m_tx_tilemap->set_scrolldy(16, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -234,106 +230,117 @@ void flower_state::draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &clipre
|
||||
*/
|
||||
void flower_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
|
||||
{
|
||||
uint8_t *spr_ptr = &m_workram[0x1e08];
|
||||
u8 *spr_ptr = &m_workram[0x1e08];
|
||||
gfx_element *gfx_2 = m_gfxdecode->gfx(2);
|
||||
|
||||
// traverse from top to bottom
|
||||
for(int i=0x1f0;i>=0;i-=8)
|
||||
for (int i = 0x1f0; i >= 0; i -= 8)
|
||||
{
|
||||
uint8_t tile = (spr_ptr[i+1] & 0x3f);
|
||||
uint8_t color = spr_ptr[i+6] >> 4;
|
||||
int x = (spr_ptr[i+4] | (spr_ptr[i+5]<<8))-39;
|
||||
int y = 241-spr_ptr[i+0];
|
||||
uint8_t attr = spr_ptr[i+2];
|
||||
uint8_t fy = spr_ptr[i+1] & 0x80;
|
||||
uint8_t fx = spr_ptr[i+1] & 0x40;
|
||||
uint8_t ysize = ((spr_ptr[i+3] & 0x80) >> 7) + 1;
|
||||
uint8_t xsize = ((spr_ptr[i+3] & 0x08) >> 3) + 1;
|
||||
uint8_t ydiv = ysize == 2 ? 1 : 2;
|
||||
uint8_t xdiv = xsize == 2 ? 1 : 2;
|
||||
uint32_t yshrink_zoom = ((spr_ptr[i+3] & 0x70) >> 4) + 1;
|
||||
uint32_t xshrink_zoom = ((spr_ptr[i+3] & 0x07) >> 0) + 1;
|
||||
u32 tile = (spr_ptr[i + 1] & 0x3f);
|
||||
const u32 color = spr_ptr[i + 6] >> 4;
|
||||
int x = (spr_ptr[i + 4] | (spr_ptr[i + 5] << 8)) - 39;
|
||||
int y = 241 - spr_ptr[i + 0];
|
||||
const u8 attr = spr_ptr[i + 2];
|
||||
const bool fy = spr_ptr[i + 1] & 0x80;
|
||||
const bool fx = spr_ptr[i + 1] & 0x40;
|
||||
const u8 ysize = ((spr_ptr[i + 3] & 0x80) >> 7) + 1;
|
||||
const u8 xsize = ((spr_ptr[i + 3] & 0x08) >> 3) + 1;
|
||||
const u8 ydiv = ysize == 2 ? 1 : 2;
|
||||
const u8 xdiv = xsize == 2 ? 1 : 2;
|
||||
u32 yshrink_zoom = ((spr_ptr[i + 3] & 0x70) >> 4) + 1;
|
||||
u32 xshrink_zoom = ((spr_ptr[i + 3] & 0x07) >> 0) + 1;
|
||||
yshrink_zoom <<= 13;
|
||||
xshrink_zoom <<= 13;
|
||||
int ypixels = (yshrink_zoom*16) >> 16;
|
||||
int xpixels = (xshrink_zoom*16) >> 16;
|
||||
const int ypixels = (yshrink_zoom * 16) >> 16;
|
||||
const int xpixels = (xshrink_zoom * 16) >> 16;
|
||||
|
||||
tile |= (attr & 1) << 6;
|
||||
tile |= (attr & 8) << 4;
|
||||
|
||||
if(flip_screen())
|
||||
if (m_flip_screen)
|
||||
{
|
||||
x += xsize*16;
|
||||
x = 288-x;
|
||||
x += xsize * 16;
|
||||
x = 288 - x;
|
||||
y -= 2;
|
||||
}
|
||||
|
||||
if(ysize == 2)
|
||||
y-=16;
|
||||
if (ysize == 2)
|
||||
y -= 16;
|
||||
|
||||
for(int yi=0;yi<ysize;yi++)
|
||||
for (int yi = 0; yi < ysize; yi++)
|
||||
{
|
||||
int yoffs = (16-ypixels)/ydiv;
|
||||
const int yoffs = (16 - ypixels) / ydiv;
|
||||
|
||||
for(int xi=0;xi<xsize;xi++)
|
||||
for (int xi = 0; xi < xsize; xi++)
|
||||
{
|
||||
int tile_offs;
|
||||
int xoffs = (16-xpixels)/xdiv;
|
||||
const int xoffs = (16 - xpixels) / xdiv;
|
||||
|
||||
tile_offs = fx ? (xsize-xi-1) * 8 : xi*8;
|
||||
tile_offs+= fy ? (ysize-yi-1) : yi;
|
||||
tile_offs = fx ? (xsize - xi - 1) * 8 : xi * 8;
|
||||
tile_offs += fy ? (ysize - yi - 1) : yi;
|
||||
|
||||
gfx_2->zoom_transpen(bitmap,cliprect, tile+tile_offs, color, fx, fy, x+xi*xpixels+xoffs, y+yi*ypixels+yoffs, xshrink_zoom, yshrink_zoom, 15);
|
||||
gfx_2->zoom_transpen(bitmap, cliprect,
|
||||
tile + tile_offs, color,
|
||||
fx, fy,
|
||||
x + xi * xpixels + xoffs, y + yi * ypixels + yoffs,
|
||||
xshrink_zoom, yshrink_zoom,
|
||||
15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t flower_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
|
||||
u32 flower_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
|
||||
{
|
||||
m_bg_tilemap->set_scrolly(0, m_bgscroll[0]);
|
||||
m_fg_tilemap->set_scrolly(0, m_fgscroll[0]);
|
||||
|
||||
m_temp_bitmap.fill(0,cliprect);
|
||||
m_temp_bitmap.fill(0, cliprect);
|
||||
m_bg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0);
|
||||
m_fg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0);
|
||||
draw_sprites(m_temp_bitmap,cliprect);
|
||||
draw_legacy_text(m_temp_bitmap,cliprect);
|
||||
draw_sprites(m_temp_bitmap, cliprect);
|
||||
m_tx_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0);
|
||||
|
||||
copybitmap(bitmap,m_temp_bitmap,m_flip_screen,m_flip_screen,m_flip_screen == true ? -154 : 0, m_flip_screen == true ? -7 : 0, cliprect);
|
||||
copybitmap(bitmap, m_temp_bitmap, m_flip_screen, m_flip_screen, m_flip_screen ? -96 : 0, m_flip_screen ? -8 : 0, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flower_state::flipscreen_w(uint8_t data)
|
||||
void flower_state::flipscreen_w(u8 data)
|
||||
{
|
||||
flip_screen_set(data & 1);
|
||||
m_flip_screen = BIT(data,0);
|
||||
m_flip_screen = BIT(data, 0);
|
||||
//flip_screen_set(m_flip_screen);
|
||||
}
|
||||
|
||||
void flower_state::coin_counter_w(uint8_t data)
|
||||
void flower_state::coin_counter_w(u8 data)
|
||||
{
|
||||
machine().bookkeeping().coin_counter_w(0,data & 1);
|
||||
machine().bookkeeping().coin_counter_w(0, BIT(data, 0));
|
||||
}
|
||||
|
||||
void flower_state::sound_command_w(uint8_t data)
|
||||
void flower_state::sound_command_w(u8 data)
|
||||
{
|
||||
m_soundlatch->write(data & 0xff);
|
||||
if(m_audio_nmi_enable == true)
|
||||
m_soundlatch->write(data);
|
||||
if (m_audio_nmi_enable)
|
||||
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
void flower_state::audio_nmi_mask_w(uint8_t data)
|
||||
void flower_state::audio_nmi_mask_w(u8 data)
|
||||
{
|
||||
m_audio_nmi_enable = BIT(data,0);
|
||||
m_audio_nmi_enable = BIT(data, 0);
|
||||
}
|
||||
|
||||
void flower_state::bgvram_w(offs_t offset, uint8_t data)
|
||||
void flower_state::txvram_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_txvram[offset] = data;
|
||||
m_tx_tilemap->mark_tile_dirty(offset & 0x3ff);
|
||||
}
|
||||
|
||||
void flower_state::bgvram_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_bgvram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset & 0xff);
|
||||
}
|
||||
|
||||
void flower_state::fgvram_w(offs_t offset, uint8_t data)
|
||||
void flower_state::fgvram_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_fgvram[offset] = data;
|
||||
m_fg_tilemap->mark_tile_dirty(offset & 0xff);
|
||||
@ -354,7 +361,7 @@ void flower_state::shared_map(address_map &map)
|
||||
map(0xa102, 0xa102).portr("DSW1");
|
||||
map(0xa103, 0xa103).portr("DSW2");
|
||||
map(0xa400, 0xa400).w(FUNC(flower_state::sound_command_w));
|
||||
map(0xe000, 0xefff).ram().share("txvram");
|
||||
map(0xe000, 0xefff).ram().w(FUNC(flower_state::txvram_w)).share("txvram");
|
||||
map(0xf000, 0xf1ff).ram().w(FUNC(flower_state::fgvram_w)).share("fgvram");
|
||||
map(0xf200, 0xf200).ram().share("fgscroll");
|
||||
map(0xf800, 0xf9ff).ram().w(FUNC(flower_state::bgvram_w)).share("bgvram");
|
||||
@ -399,7 +406,7 @@ static INPUT_PORTS_START( flower )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("DSW1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, flower_state,coin_inserted, 0)
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, flower_state, coin_inserted, 0)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_DIPNAME( 0x08, 0x08, "Energy Decrease" ) PORT_DIPLOCATION("SW2:4")
|
||||
@ -467,9 +474,9 @@ static const gfx_layout tilelayout =
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_flower )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 64 )
|
||||
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 16 )
|
||||
GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 0, 16 )
|
||||
GFXDECODE_ENTRY( "text", 0, charlayout, 0, 64 )
|
||||
GFXDECODE_ENTRY( "tiles", 0, tilelayout, 0, 16 )
|
||||
GFXDECODE_ENTRY( "sprites", 0, tilelayout, 0, 16 )
|
||||
GFXDECODE_END
|
||||
|
||||
void flower_state::machine_start()
|
||||
@ -484,28 +491,28 @@ void flower_state::machine_reset()
|
||||
|
||||
INTERRUPT_GEN_MEMBER(flower_state::master_vblank_irq)
|
||||
{
|
||||
//if(m_master_irq_enable == true)
|
||||
//if (m_master_irq_enable)
|
||||
device.execute().set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(flower_state::slave_vblank_irq)
|
||||
{
|
||||
//if(m_slave_irq_enable == true)
|
||||
//if (m_slave_irq_enable)
|
||||
device.execute().set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
|
||||
void flower_state::flower(machine_config &config)
|
||||
{
|
||||
Z80(config, m_mastercpu, MASTER_CLOCK/4);
|
||||
Z80(config, m_mastercpu, MASTER_CLOCK / 4); // divider unknown
|
||||
m_mastercpu->set_addrmap(AS_PROGRAM, &flower_state::shared_map);
|
||||
m_mastercpu->set_vblank_int("screen", FUNC(flower_state::master_vblank_irq));
|
||||
|
||||
Z80(config, m_slavecpu, MASTER_CLOCK/4);
|
||||
Z80(config, m_slavecpu, MASTER_CLOCK / 4); // divider unknown
|
||||
m_slavecpu->set_addrmap(AS_PROGRAM, &flower_state::shared_map);
|
||||
m_slavecpu->set_vblank_int("screen", FUNC(flower_state::slave_vblank_irq));
|
||||
|
||||
Z80(config, m_audiocpu, MASTER_CLOCK/4);
|
||||
Z80(config, m_audiocpu, MASTER_CLOCK / 4); // divider unknown
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &flower_state::audio_map);
|
||||
m_audiocpu->set_periodic_int(FUNC(flower_state::irq0_line_hold), attotime::from_hz(90));
|
||||
|
||||
@ -513,7 +520,7 @@ void flower_state::flower(machine_config &config)
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_screen_update(FUNC(flower_state::screen_update));
|
||||
m_screen->set_raw(MASTER_CLOCK/3,384,0,288,264,16,240); // derived from Galaxian HW, 60.606060
|
||||
m_screen->set_raw(MASTER_CLOCK / 3, 384, 0, 288, 264, 16, 240); // derived from Galaxian HW, 60.606060
|
||||
m_screen->set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_flower);
|
||||
@ -537,25 +544,25 @@ ROM_START( flower ) /* Komax version */
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
|
||||
ROM_LOAD( "3.d9", 0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) // 1xxxxxxxxxxxxx = 0xFF
|
||||
|
||||
ROM_REGION( 0x2000, "gfx1", ROMREGION_INVERT ) /* tx layer */
|
||||
ROM_REGION( 0x2000, "text", ROMREGION_INVERT ) /* tx layer */
|
||||
ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) // FIRST AND SECOND HALF IDENTICAL
|
||||
|
||||
ROM_REGION( 0x8000, "gfx2", ROMREGION_INVERT ) /* bg layers */
|
||||
ROM_REGION( 0x8000, "tiles", ROMREGION_INVERT ) /* bg layers */
|
||||
ROM_LOAD( "8.10e", 0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) )
|
||||
ROM_LOAD( "6.7e", 0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) )
|
||||
ROM_LOAD( "9.12e", 0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) )
|
||||
ROM_LOAD( "15.9e", 0x6000, 0x2000, CRC(1cad9f72) SHA1(c38dbea266246ed4d47d12bdd8f9fae22a5f8bb8) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx3", ROMREGION_INVERT ) /* sprites */
|
||||
ROM_REGION( 0x8000, "sprites", ROMREGION_INVERT ) /* sprites */
|
||||
ROM_LOAD( "14.19e", 0x0000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) )
|
||||
ROM_LOAD( "13.17e", 0x2000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) )
|
||||
ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) )
|
||||
ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) )
|
||||
|
||||
ROM_REGION( 0x8000, "samples", 0 )
|
||||
ROM_REGION( 0x8000, "flower:samples", 0 )
|
||||
ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */
|
||||
|
||||
ROM_REGION( 0x4000, "soundvol", 0 )
|
||||
ROM_REGION( 0x4000, "flower:soundvol", 0 )
|
||||
ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */
|
||||
|
||||
ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */
|
||||
@ -580,25 +587,25 @@ ROM_START( flowerj ) /* Sega/Alpha version. Sega game number 834-5998 */
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
|
||||
ROM_LOAD( "3.d9", 0x0000, 0x4000, CRC(8866c2b0) SHA1(d00f31994673e8087a1406f98e8832d07cedeb66) ) // 1xxxxxxxxxxxxx = 0xFF
|
||||
|
||||
ROM_REGION( 0x2000, "gfx1", ROMREGION_INVERT ) /* tx layer */
|
||||
ROM_REGION( 0x2000, "text", ROMREGION_INVERT ) /* tx layer */
|
||||
ROM_LOAD( "10.13e", 0x0000, 0x2000, CRC(62f9b28c) SHA1(d57d06b99e72a4f68f197a5b6c042c926cc70ca0) ) // FIRST AND SECOND HALF IDENTICAL
|
||||
|
||||
ROM_REGION( 0x8000, "gfx2", ROMREGION_INVERT ) /* bg layers */
|
||||
ROM_REGION( 0x8000, "tiles", ROMREGION_INVERT ) /* bg layers */
|
||||
ROM_LOAD( "8.10e", 0x0000, 0x2000, CRC(f85eb20f) SHA1(699edc970c359143dee6de2a97cc2a552454785b) )
|
||||
ROM_LOAD( "6.7e", 0x2000, 0x2000, CRC(3e97843f) SHA1(4e4e5625dbf78eca97536b1428b2e49ad58c618f) )
|
||||
ROM_LOAD( "9.12e", 0x4000, 0x2000, CRC(f1d9915e) SHA1(158e1cc8c402f9ae3906363d99f2b25c94c64212) )
|
||||
ROM_LOAD( "7.9e", 0x6000, 0x2000, CRC(e350f36c) SHA1(f97204dc95b4000c268afc053a2333c1629e07d8) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx3", ROMREGION_INVERT ) /* sprites */
|
||||
ROM_REGION( 0x8000, "sprites", ROMREGION_INVERT ) /* sprites */
|
||||
ROM_LOAD( "14.19e", 0x0000, 0x2000, CRC(11b491c5) SHA1(be1c4a0fbe8fd4e124c21e0f700efa0428376691) )
|
||||
ROM_LOAD( "13.17e", 0x2000, 0x2000, CRC(ea743986) SHA1(bbef4fd0f7d21cc89a52061fa50d7c2ea37287bd) )
|
||||
ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) )
|
||||
ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) )
|
||||
|
||||
ROM_REGION( 0x8000, "samples", 0 )
|
||||
ROM_REGION( 0x8000, "flower:samples", 0 )
|
||||
ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */
|
||||
|
||||
ROM_REGION( 0x4000, "soundvol", 0 )
|
||||
ROM_REGION( 0x4000, "flower:soundvol", 0 )
|
||||
ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */
|
||||
|
||||
ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */
|
||||
|
Loading…
Reference in New Issue
Block a user