diff options
| author | 2025-07-22 20:11:38 +0200 | |
|---|---|---|
| committer | 2025-07-22 20:11:49 +0200 | |
| commit | fe086b54cd07fa8a96c12f38cd8d1501ecf9b511 (patch) | |
| tree | 7af80e230d2acf59d01cf1cbf8009fe19b27a813 /src | |
| parent | b077d4e9725b186540628c421c810b0cb9482bfd (diff) | |
(emu.h) drawgfx: (re)add support for high priority shadows
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/drawgfx.h | 72 | ||||
| -rw-r--r-- | src/emu/drawgfxt.ipp | 23 | ||||
| -rw-r--r-- | src/emu/xtal.h | 10 | ||||
| -rw-r--r-- | src/mame/capcom/cps3.cpp | 5 | ||||
| -rw-r--r-- | src/mame/konami/asterix.cpp | 2 | ||||
| -rw-r--r-- | src/mame/konami/chqflag.cpp | 1 | ||||
| -rw-r--r-- | src/mame/konami/k051960.cpp | 33 | ||||
| -rw-r--r-- | src/mame/konami/k051960.h | 2 | ||||
| -rw-r--r-- | src/mame/konami/k053244_k053245.cpp | 15 | ||||
| -rw-r--r-- | src/mame/konami/k053244_k053245.h | 4 | ||||
| -rw-r--r-- | src/mame/konami/surpratk.cpp | 1 | ||||
| -rw-r--r-- | src/mame/konami/xmen.cpp | 6 |
12 files changed, 95 insertions, 79 deletions
diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h index d28024bb442..11a0f5d200a 100644 --- a/src/emu/drawgfx.h +++ b/src/emu/drawgfx.h @@ -129,7 +129,8 @@ enum { DRAWMODE_NONE, DRAWMODE_SOURCE, - DRAWMODE_SHADOW + DRAWMODE_SHADOW, + DRAWMODE_SHADOW_PRI }; enum @@ -149,9 +150,6 @@ class gfx_element { public: // construction/destruction -#ifdef UNUSED_FUNCTION - gfx_element(); -#endif gfx_element(device_palette_interface *palette, const gfx_layout &gl, const u8 *srcdata, u32 xormask, u32 total_colors, u32 color_base); gfx_element(device_palette_interface *palette, u8 *base, u16 width, u16 height, u32 rowbytes, u32 total_colors, u32 color_base, u32 color_granularity); @@ -284,39 +282,39 @@ private: void decode(u32 code); // internal state - device_palette_interface *m_palette; // palette used for drawing (optional when used as a pure decoder) - - u16 m_width; // current pixel width of each element (changeable with source clipping) - u16 m_height; // current pixel height of each element (changeable with source clipping) - u16 m_startx; // current source clip X offset - u16 m_starty; // current source clip Y offset - - u16 m_origwidth; // starting pixel width of each element - u16 m_origheight; // staring pixel height of each element - u32 m_total_elements; // total number of decoded elements - - u32 m_color_base; // base color for rendering - u16 m_color_depth; // number of colors each pixel can represent - u16 m_color_granularity; // number of colors for each color code - u32 m_total_colors; // number of color codes - - u32 m_line_modulo; // bytes between each row of data - u32 m_char_modulo; // bytes between each element - const u8 * m_srcdata; // pointer to the source data for decoding - u32 m_dirtyseq; // sequence number; incremented each time a tile is dirtied - - u8 * m_gfxdata; // pointer to decoded pixel data, 8bpp - std::vector<u8> m_gfxdata_allocated; // allocated decoded pixel data, 8bpp - std::vector<u8> m_dirty; // dirty array for detecting chars that need decoding - std::vector<u32> m_pen_usage; // bitmask of pens that are used (pens 0-31 only) - - bool m_layout_is_raw; // raw layout? - u8 m_layout_planes; // bit planes in the layout - u32 m_layout_xormask; // xor mask applied to each bit offset - u32 m_layout_charincrement; // per-character increment in source data - std::vector<u32> m_layout_planeoffset;// plane offsets - std::vector<u32> m_layout_xoffset; // X offsets - std::vector<u32> m_layout_yoffset; // Y offsets + device_palette_interface *m_palette; // palette used for drawing (optional when used as a pure decoder) + + u16 m_width; // current pixel width of each element (changeable with source clipping) + u16 m_height; // current pixel height of each element (changeable with source clipping) + u16 m_startx; // current source clip X offset + u16 m_starty; // current source clip Y offset + + u16 m_origwidth; // starting pixel width of each element + u16 m_origheight; // staring pixel height of each element + u32 m_total_elements; // total number of decoded elements + + u32 m_color_base; // base color for rendering + u16 m_color_depth; // number of colors each pixel can represent + u16 m_color_granularity; // number of colors for each color code + u32 m_total_colors; // number of color codes + + u32 m_line_modulo; // bytes between each row of data + u32 m_char_modulo; // bytes between each element + const u8 * m_srcdata; // pointer to the source data for decoding + u32 m_dirtyseq; // sequence number; incremented each time a tile is dirtied + + u8 * m_gfxdata; // pointer to decoded pixel data, 8bpp + std::vector<u8> m_gfxdata_allocated; // allocated decoded pixel data, 8bpp + std::vector<u8> m_dirty; // dirty array for detecting chars that need decoding + std::vector<u32> m_pen_usage; // bitmask of pens that are used (pens 0-31 only) + + bool m_layout_is_raw; // raw layout? + u8 m_layout_planes; // bit planes in the layout + u32 m_layout_xormask; // xor mask applied to each bit offset + u32 m_layout_charincrement; // per-character increment in source data + std::vector<u32> m_layout_planeoffset; // plane offsets + std::vector<u32> m_layout_xoffset; // X offsets + std::vector<u32> m_layout_yoffset; // Y offsets }; diff --git a/src/emu/drawgfxt.ipp b/src/emu/drawgfxt.ipp index 4277bf21634..3a6ad0cad08 100644 --- a/src/emu/drawgfxt.ipp +++ b/src/emu/drawgfxt.ipp @@ -294,6 +294,11 @@ while (0) look up the pen via the 'paldata' array; if the entry is DRAWMODE_SHADOW, generate a shadow of the destination pixel using 'shadowtable' + + If the entry is DRAWMODE_SHADOW_PRI and priority + is used, shadow is reapplied to SOURCE entries + drawn underneath it. Otherwise, shadows are + presumed to be lowest priority. -------------------------------------------------*/ #define PIXEL_OP_REBASE_TRANSTABLE16(DEST, SOURCE) \ @@ -335,13 +340,18 @@ do if (entry == DRAWMODE_SOURCE) \ { \ if (((1 << (pridata & 0x1f)) & pmask) == 0) \ - (DEST) = color + srcdata; \ + { \ + if ((pridata & 0xc0) == (DRAWMODE_SHADOW_PRI << 6)) \ + (DEST) = shadowtable[u16(color + srcdata)]; \ + else \ + (DEST) = color + srcdata; \ + } \ (PRIORITY) = 31; \ } \ else if ((pridata & 0x80) == 0 && ((1 << (pridata & 0x1f)) & pmask) == 0) \ { \ (DEST) = shadowtable[DEST]; \ - (PRIORITY) = pridata | 0x80; \ + (PRIORITY) = pridata | (entry << 6); \ } \ } \ } \ @@ -357,13 +367,18 @@ do if (entry == DRAWMODE_SOURCE) \ { \ if (((1 << (pridata & 0x1f)) & pmask) == 0) \ - (DEST) = paldata[srcdata]; \ + { \ + if ((pridata & 0xc0) == (DRAWMODE_SHADOW_PRI << 6)) \ + (DEST) = shadowtable[rgb_t(paldata[srcdata]).as_rgb15()]; \ + else \ + (DEST) = paldata[srcdata]; \ + } \ (PRIORITY) = 31; \ } \ else if ((pridata & 0x80) == 0 && ((1 << (pridata & 0x1f)) & pmask) == 0) \ { \ (DEST) = shadowtable[rgb_t(DEST).as_rgb15()]; \ - (PRIORITY) = pridata | 0x80; \ + (PRIORITY) = pridata | (entry << 6); \ } \ } \ } \ diff --git a/src/emu/xtal.h b/src/emu/xtal.h index b58f00943b2..356ca6eb308 100644 --- a/src/emu/xtal.h +++ b/src/emu/xtal.h @@ -9,16 +9,17 @@ Usage: + When you're 100% sure there is a given crystal or resonator on a PCB, use XTAL(frequency) to document so. That xtal object then collates multiplies or divides done to the base frequency to compute the final one. - If you recieve a XTAL object and want to turn it to a final + If you receive a XTAL object and want to turn it to a final frequency, use value() to get an integer or dvalue() to get a double. - If you recieve a XTAL object and want to check if the initial + If you receive a XTAL object and want to check if the initial crystal value is sane, use check(context message). It will fatalerror if the value is not in the authorized value list. It has a (small) cost, so don't do it in a hot path. @@ -35,7 +36,6 @@ Usage: ***************************************************************************/ - #ifndef MAME_EMU_XTAL_H #define MAME_EMU_XTAL_H @@ -43,9 +43,9 @@ Usage: #pragma once -class XTAL { +class XTAL +{ public: - constexpr explicit XTAL(double base_clock) : m_base_clock(base_clock), m_current_clock(base_clock) {} constexpr double dvalue() const noexcept { return m_current_clock; } diff --git a/src/mame/capcom/cps3.cpp b/src/mame/capcom/cps3.cpp index e34ce69f38e..67d334f8066 100644 --- a/src/mame/capcom/cps3.cpp +++ b/src/mame/capcom/cps3.cpp @@ -616,10 +616,6 @@ inline void cps3_state::cps3_drawgfxzoom(bitmap_rgb32 &dest_bmp,const rectangle int transparency,int transparent_color, int scalex, int scaley) { -// u8 al; - -// al = (pdrawgfx_shadow_lowpri) ? 0 : 0x80; - if (!scalex || !scaley) return; // todo: reimplement this optimization!! @@ -636,7 +632,6 @@ inline void cps3_state::cps3_drawgfxzoom(bitmap_rgb32 &dest_bmp,const rectangle 1<<17 : double to 200% */ - /* force clip to bitmap boundary */ rectangle myclip = clip; myclip &= dest_bmp.cliprect(); diff --git a/src/mame/konami/asterix.cpp b/src/mame/konami/asterix.cpp index 0d584fdd2a4..91142d10f0d 100644 --- a/src/mame/konami/asterix.cpp +++ b/src/mame/konami/asterix.cpp @@ -186,8 +186,6 @@ uint32_t asterix_state::screen_update_asterix(screen_device &screen, bitmap_ind1 m_k056832->tilemap_draw(screen, bitmap, cliprect, layer[1], K056832_DRAW_FLAG_MIRROR, 2); m_k056832->tilemap_draw(screen, bitmap, cliprect, layer[2], K056832_DRAW_FLAG_MIRROR, 4); - /* this isn't supported anymore and it is unsure if still needed; keeping here for reference - pdrawgfx_shadow_lowpri = 1; fix shadows in front of feet */ m_k053244->sprites_draw(bitmap, cliprect, screen.priority()); m_k056832->tilemap_draw(screen, bitmap, cliprect, 2, K056832_DRAW_FLAG_MIRROR, 0); diff --git a/src/mame/konami/chqflag.cpp b/src/mame/konami/chqflag.cpp index 0786648e411..08c9f8c67d7 100644 --- a/src/mame/konami/chqflag.cpp +++ b/src/mame/konami/chqflag.cpp @@ -437,6 +437,7 @@ void chqflag_state::chqflag(machine_config &config) m_k051960->set_palette(m_palette); m_k051960->set_screen("screen"); m_k051960->set_sprite_callback(FUNC(chqflag_state::sprite_callback)); + m_k051960->set_priority_shadows(true); m_k051960->k051937_shadow_mode().set(m_palette, FUNC(palette_device::set_shadow_mode)); m_k051960->irq_handler().set_inputline(m_maincpu, KONAMI_IRQ_LINE); m_k051960->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI); diff --git a/src/mame/konami/k051960.cpp b/src/mame/konami/k051960.cpp index 4a3a45f65c6..4e93122613e 100644 --- a/src/mame/konami/k051960.cpp +++ b/src/mame/konami/k051960.cpp @@ -151,6 +151,7 @@ k051960_device::k051960_device(const machine_config &mconfig, const char *tag, d , m_romoffset(0) , m_control(0) , m_shadow_config(0) + , m_priority_shadows(false) { } @@ -291,15 +292,13 @@ TIMER_CALLBACK_MEMBER(k051960_device::nmi_scanline) u8 k051960_device::k051960_fetchromdata(offs_t offset) { - int code, color, pri, off1, addr; - bool shadow; - - addr = m_romoffset + (m_spriterombank[0] << 8) + ((m_spriterombank[1] & 0x03) << 16); - code = (addr & 0x3ffe0) >> 5; - off1 = addr & 0x1f; - color = ((m_spriterombank[1] & 0xfc) >> 2) + ((m_spriterombank[2] & 0x03) << 6); - pri = 0; - shadow = false; + int addr = m_romoffset + (m_spriterombank[0] << 8) + ((m_spriterombank[1] & 0x03) << 16); + int code = (addr & 0x3ffe0) >> 5; + int off1 = addr & 0x1f; + int color = ((m_spriterombank[1] & 0xfc) >> 2) + ((m_spriterombank[2] & 0x03) << 6); + int pri = 0; + bool shadow = false; + m_k051960_cb(&code, &color, &pri, &shadow); addr = (code << 7) | (off1 << 2) | offset; @@ -427,6 +426,8 @@ void k051960_device::k051960_sprites_draw(bitmap_ind16 &bitmap, const rectangle memset(drawmode_table, DRAWMODE_SOURCE, sizeof(drawmode_table)); drawmode_table[0] = DRAWMODE_NONE; + const u32 shadow_mode = (m_priority_shadows || palette().shadow_mode()) ? DRAWMODE_SHADOW_PRI : DRAWMODE_SHADOW; + for (offs = 0; offs < NUM_SPRITES; offs++) sortedlist[offs] = -1; @@ -445,8 +446,7 @@ void k051960_device::k051960_sprites_draw(bitmap_ind16 &bitmap, const rectangle for (pri_code = 0; pri_code < NUM_SPRITES; pri_code++) { - int ox, oy, code, color, pri, size, w, h, x, y, flipx, flipy, zoomx, zoomy; - bool shadow; + int ox, oy, size, w, h, x, y, flipx, flipy, zoomx, zoomy; /* sprites can be grouped up to 8x8. The draw order is 0 1 4 5 16 17 20 21 2 3 6 7 18 19 22 23 @@ -466,10 +466,11 @@ void k051960_device::k051960_sprites_draw(bitmap_ind16 &bitmap, const rectangle if (offs == -1) continue; - code = m_buffer[offs + 2] + ((m_buffer[offs + 1] & 0x1f) << 8); - color = m_buffer[offs + 3] & 0xff; - pri = 0; - shadow = !BIT(m_shadow_config, 2) && (BIT(m_shadow_config, 1) || BIT(color, 7)); + int code = m_buffer[offs + 2] + ((m_buffer[offs + 1] & 0x1f) << 8); + int color = m_buffer[offs + 3] & 0xff; + int pri = 0; + bool shadow = !BIT(m_shadow_config, 2) && (BIT(m_shadow_config, 1) || BIT(color, 7)); + m_k051960_cb(&code, &color, &pri, &shadow); if (max_priority != -1) @@ -529,7 +530,7 @@ void k051960_device::k051960_sprites_draw(bitmap_ind16 &bitmap, const rectangle flipy = !flipy; } - drawmode_table[gfx(0)->granularity() - 1] = shadow ? DRAWMODE_SHADOW : DRAWMODE_SOURCE; + drawmode_table[gfx(0)->granularity() - 1] = shadow ? shadow_mode : DRAWMODE_SOURCE; if (zoomx == 0x10000 && zoomy == 0x10000) { diff --git a/src/mame/konami/k051960.h b/src/mame/konami/k051960.h index 5db963bd851..d79f8f47d5d 100644 --- a/src/mame/konami/k051960.h +++ b/src/mame/konami/k051960.h @@ -36,6 +36,7 @@ public: auto nmi_handler() { return m_nmi_handler.bind(); } auto k051937_shadow_mode() { return m_shadow_config_cb.bind(); } + void set_priority_shadows(bool pri) { m_priority_shadows = pri; } /* The sprite callback is passed: @@ -90,6 +91,7 @@ private: u8 m_control; emu_timer *m_sprites_busy; u8 m_shadow_config; + bool m_priority_shadows; u8 k051960_fetchromdata(offs_t offset); diff --git a/src/mame/konami/k053244_k053245.cpp b/src/mame/konami/k053244_k053245.cpp index cfa2eae1b42..fd3e505d76f 100644 --- a/src/mame/konami/k053244_k053245.cpp +++ b/src/mame/konami/k053244_k053245.cpp @@ -88,6 +88,7 @@ k053244_device::k053244_device(const machine_config &mconfig, const char *tag, d m_sprite_rom(*this, DEVICE_SELF), m_dx(0), m_dy(0), + m_priority_shadows(false), m_k053244_cb(*this), m_rombank(0), m_ramsize(0), @@ -311,6 +312,10 @@ void k053244_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &clipre memset(drawmode_table, DRAWMODE_SOURCE, sizeof(drawmode_table)); drawmode_table[0] = DRAWMODE_NONE; + // high priority shadows are enabled in tmnt2 and ssriders highlights (but not the shadows) + // also in suratk (enemies behind the glass) + const uint32_t shadow_mode = (m_priority_shadows || palette().shadow_mode()) ? DRAWMODE_SHADOW_PRI : DRAWMODE_SHADOW; + flipscreenX = m_regs[5] & 0x01; flipscreenY = m_regs[5] & 0x02; spriteoffsX = (m_regs[0] << 8) | m_regs[1]; @@ -337,7 +342,7 @@ void k053244_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &clipre for (pri_code = NUM_SPRITES - 1; pri_code >= 0; pri_code--) { - int ox, oy, color, code, size, w, h, x, y, flipx, flipy, mirrorx, mirrory, shadow, zoomx, zoomy, pri; + int ox, oy, size, w, h, x, y, flipx, flipy, mirrorx, mirrory, shadow, zoomx, zoomy; offs = sortedlist[pri_code]; if (offs == -1) @@ -370,11 +375,11 @@ void k053244_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &clipre /* field to do bank switching. However this applies only to TMNT2, with its */ /* protection mcu creating the sprite table, so we don't know where to fetch */ /* the bits from. */ - code = m_buffer[offs + 1]; + int code = m_buffer[offs + 1]; code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1) + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2)); - color = m_buffer[offs + 6] & 0x00ff; - pri = 0; + int color = m_buffer[offs + 6] & 0x00ff; + int pri = 0; if (!m_k053244_cb.isnull()) m_k053244_cb(&code, &color, &pri); @@ -449,7 +454,7 @@ void k053244_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &clipre ox -= (zoomx * w) >> 13; oy -= (zoomy * h) >> 13; - drawmode_table[gfx(0)->granularity() - 1] = shadow ? DRAWMODE_SHADOW : DRAWMODE_SOURCE; + drawmode_table[gfx(0)->granularity() - 1] = shadow ? shadow_mode : DRAWMODE_SOURCE; for (y = 0; y < h; y++) { diff --git a/src/mame/konami/k053244_k053245.h b/src/mame/konami/k053244_k053245.h index 27e51720bcd..c35fdeae4b3 100644 --- a/src/mame/konami/k053244_k053245.h +++ b/src/mame/konami/k053244_k053245.h @@ -6,7 +6,7 @@ #pragma once -#define K053244_CB_MEMBER(_name) void _name(int *code, int *color, int *priority) +#define K053244_CB_MEMBER(_name) void _name(int *code, int *color, int *priority) class k053244_device : public device_t, public device_gfx_interface @@ -25,6 +25,7 @@ public: void set_bpp(int bpp); template <typename... T> void set_sprite_callback(T &&... args) { m_k053244_cb.set(std::forward<T>(args)...); } void set_offsets(int dx, int dy) { m_dx = dx; m_dy = dy; } + void set_priority_shadows(bool pri) { m_priority_shadows = pri; } u16 k053245_word_r(offs_t offset); void k053245_word_w(offs_t offset, u16 data, u16 mem_mask = ~0); @@ -48,6 +49,7 @@ private: required_region_ptr<uint8_t> m_sprite_rom; int m_dx, m_dy; + bool m_priority_shadows; sprite_delegate m_k053244_cb; uint8_t m_regs[0x10]; // 053244 diff --git a/src/mame/konami/surpratk.cpp b/src/mame/konami/surpratk.cpp index 7ecca18028c..77e44c860c7 100644 --- a/src/mame/konami/surpratk.cpp +++ b/src/mame/konami/surpratk.cpp @@ -327,6 +327,7 @@ void surpratk_state::surpratk(machine_config &config) K053244(config, m_k053244, 24_MHz_XTAL); m_k053244->set_palette(m_palette); m_k053244->set_sprite_callback(FUNC(surpratk_state::sprite_callback)); + m_k053244->set_priority_shadows(true); K053251(config, m_k053251, 0); diff --git a/src/mame/konami/xmen.cpp b/src/mame/konami/xmen.cpp index d35af5ec3a2..dc7c2ce5e87 100644 --- a/src/mame/konami/xmen.cpp +++ b/src/mame/konami/xmen.cpp @@ -251,12 +251,11 @@ uint32_t xmen_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, screen.priority().fill(0, cliprect); bitmap.fill(16 * bg_colorbase + 1, cliprect); // note the '+1' in the background color! + m_k052109->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 1); m_k052109->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2); m_k052109->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4); - /* this isn't supported anymore and it is unsure if still needed; keeping here for reference - pdrawgfx_shadow_lowpri = 1; fix shadows of boulders in front of feet */ m_k053246->k053247_sprites_draw(bitmap, cliprect); return 0; } @@ -329,12 +328,11 @@ void xmen6p_state::screen_vblank(int state) m_screen->priority().fill(0, cliprect); renderbitmap.fill(16 * bg_colorbase + 1, cliprect); // note the '+1' in the background color! + m_k052109->tilemap_draw(*m_screen, renderbitmap, cliprect, layer[0], 0, 1); m_k052109->tilemap_draw(*m_screen, renderbitmap, cliprect, layer[1], 0, 2); m_k052109->tilemap_draw(*m_screen, renderbitmap, cliprect, layer[2], 0, 4); - /* this isn't supported anymore and it is unsure if still needed; keeping here for reference - pdrawgfx_shadow_lowpri = 1; fix shadows of boulders in front of feet */ m_k053246->k053247_sprites_draw(renderbitmap, cliprect); } } |
