From 750f28cecdd73b30c9e727afbd7caf20175a9e97 Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Wed, 31 Aug 2022 22:31:10 +0200 Subject: taito/galastrm.cpp, taito/gunbustr.cpp, taito/msisaac.cpp: consolidated drivers in single files, minor cleanups --- src/mame/taito/galastrm.cpp | 715 ++++++++++++++++++++++++++++++++++++++++-- src/mame/taito/galastrm.h | 111 ------- src/mame/taito/galastrm_v.cpp | 535 ------------------------------- src/mame/taito/groundfx.cpp | 6 +- src/mame/taito/gunbustr.cpp | 435 +++++++++++++++++++++---- src/mame/taito/gunbustr.h | 79 ----- src/mame/taito/gunbustr_v.cpp | 232 -------------- src/mame/taito/msisaac.cpp | 507 +++++++++++++++++++++++++----- src/mame/taito/msisaac.h | 116 ------- src/mame/taito/msisaac_v.cpp | 241 -------------- 10 files changed, 1486 insertions(+), 1491 deletions(-) delete mode 100644 src/mame/taito/galastrm.h delete mode 100644 src/mame/taito/galastrm_v.cpp delete mode 100644 src/mame/taito/gunbustr.h delete mode 100644 src/mame/taito/gunbustr_v.cpp delete mode 100644 src/mame/taito/msisaac.h delete mode 100644 src/mame/taito/msisaac_v.cpp diff --git a/src/mame/taito/galastrm.cpp b/src/mame/taito/galastrm.cpp index bd09bb323e6..60e91bd3627 100644 --- a/src/mame/taito/galastrm.cpp +++ b/src/mame/taito/galastrm.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Hau +// copyright-holders: Hau + /* Galactic Storm @@ -28,7 +29,7 @@ ENSONIQ 5701,5510,5505 OSC1:16MHz OSC2:30.47618MHz ---------------------------------------------------------- -based on driver from drivers/gunbustr.cpp by Bryan McPhail & David Graves +based on driver from taito/gunbustr.cpp by Bryan McPhail & David Graves Written by Hau 07/03/2008 @@ -44,16 +45,664 @@ TODO: #include "emu.h" + +#include "taito_en.h" +#include "taitoio.h" +#include "tc0100scn.h" +#include "tc0110pcr.h" +#include "tc0480scp.h" + #include "cpu/m68000/m68000.h" #include "machine/adc0808.h" #include "machine/eepromser.h" -#include "taitoio.h" #include "sound/es5506.h" -#include "taito_en.h" +#include "video/poly.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" -#include "galastrm.h" +// configurable logging +#define LOG_BADSPRITES (1U << 1) + +//#define VERBOSE (LOG_GENERAL | LOG_BADSPRITES) + +#include "logmacro.h" + +#define LOGBADSPRITES(...) LOGMASKED(LOG_BADSPRITES, __VA_ARGS__) + + +namespace { + +class galastrm_state; + +struct gs_poly_data +{ + bitmap_ind16* texbase = nullptr; +}; + +class galastrm_renderer : public poly_manager +{ +public: + galastrm_renderer(galastrm_state &state); + + void tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid); + void tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip); + + bitmap_ind16 &screenbits() { return m_screenbits; } + +private: + galastrm_state& m_state; + bitmap_ind16 m_screenbits; +}; + + +class galastrm_state : public driver_device +{ + friend class galastrm_renderer; +public: + galastrm_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_spriteram(*this,"spriteram"), + m_spritemap_rom(*this, "sprmaprom"), + m_maincpu(*this, "maincpu"), + m_eeprom(*this, "eeprom"), + m_tc0100scn(*this, "tc0100scn"), + m_tc0110pcr(*this, "tc0110pcr"), + m_tc0480scp(*this, "tc0480scp"), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen") + { } + + void galastrm(machine_config &config); + DECLARE_READ_LINE_MEMBER(frame_counter_r); + +protected: + virtual void video_start() override; + +private: + required_shared_ptr m_spriteram; + + required_region_ptr m_spritemap_rom; + + required_device m_maincpu; + required_device m_eeprom; + required_device m_tc0100scn; + required_device m_tc0110pcr; + required_device m_tc0480scp; + required_device m_gfxdecode; + required_device m_screen; + + struct gs_tempsprite + { + u8 gfx = 0U; + u32 code = 0U, color = 0U; + bool flipx = false, flipy = false; + int x = 0, y = 0; + int zoomx = 0, zoomy = 0; + u32 primask = 0U; + }; + + u16 m_frame_counter = 0U; + u16 m_tc0610_addr[2]{}; + s16 m_tc0610_ctrl_reg[2][8]{}; + std::unique_ptr m_spritelist{}; + struct gs_tempsprite *m_sprite_ptr_pre{}; + bitmap_ind16 m_tmpbitmaps{}; + std::unique_ptr m_poly{}; + + s16 m_rsxb = 0; + s16 m_rsyb = 0; + s32 m_rsxoffs = 0; + s32 m_rsyoffs = 0; + + static constexpr u8 X_OFFSET = 96; + static constexpr u8 Y_OFFSET = 60; + + template void tc0610_w(offs_t offset, u16 data); + void coin_word_w(u8 data); + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(interrupt); + void draw_sprites_pre(int x_offs, int y_offs); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority); + + void main_map(address_map &map); +}; + + +// video + +galastrm_renderer::galastrm_renderer(galastrm_state& state) + : poly_manager(state.machine()) + , m_state(state) + , m_screenbits(state.m_screen->width(), state.m_screen->height()) +{ +} + + +/******************************************************************/ + +void galastrm_state::video_start() +{ + m_spritelist = std::make_unique(0x4000); + + m_poly = std::make_unique(*this); + + m_screen->register_screen_bitmap(m_tmpbitmaps); + m_screen->register_screen_bitmap(m_poly->screenbits()); + + save_item(NAME(m_rsxb)); + save_item(NAME(m_rsyb)); + save_item(NAME(m_rsxoffs)); + save_item(NAME(m_rsyoffs)); + save_item(NAME(m_frame_counter)); + save_item(NAME(m_tc0610_addr)); + save_item(NAME(m_tc0610_ctrl_reg)); +} + + +/************************************************************ + SPRITE DRAW ROUTINES + +We draw a series of small tiles ("chunks") together to +create each big sprite. The spritemap ROM provides the lookup +table for this. The game hardware looks up 16x16 sprite chunks +from the spritemap ROM, creating a 64x64 sprite like this: + + 0 1 2 3 + 4 5 6 7 + 8 9 10 11 + 12 13 14 15 + +(where the number is the word offset into the spritemap ROM). +It can also create 32x32 sprites. + +NB: unused portions of the spritemap ROM contain hex FF's. +It is a useful coding check to warn in the log if these +are being accessed. [They can be inadvertently while +spriteram is being tested, take no notice of that.] + +Heavy use is made of sprite zooming. + + *** + + Sprite table layout (4 long words per entry) + + ------------------------------------------ + 0 | ........ x....... ........ ........ | Flip X + 0 | ........ .xxxxxxx ........ ........ | ZoomX + 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile + | | + 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*] + 2 | ........ ......xx xxxxxx.. ........ | Palette bank + 2 | ........ ........ ......xx xxxxxxxx | X position + | | + 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64) + 3 | ........ ......x. ........ ........ | Flip Y + 3 | ........ .......x xxxxxx.. ........ | ZoomY + 3 | ........ ........ ......xx xxxxxxxx | Y position + ------------------------------------------ + + [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???] + +********************************************************/ + +void galastrm_state::draw_sprites_pre(int x_offs, int y_offs) +{ + int sprites_flipscreen = 0; + + /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list + while processing sprite ram and then draw them all at the end */ + m_sprite_ptr_pre = m_spritelist.get(); + + for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4) + { + u32 data = m_spriteram[offs + 0]; + int flipx = (data & 0x00800000) >> 23; + int zoomx = (data & 0x007f0000) >> 16; + const u32 tilenum = (data & 0x00007fff); + + if (!tilenum) continue; + + data = m_spriteram[offs + 2]; + const int priority = (data & 0x000c0000) >> 18; + int color = (data & 0x0003fc00) >> 10; + int x = (data & 0x000003ff); + + data = m_spriteram[offs + 3]; + const int dblsize = (data & 0x00040000) >> 18; + int flipy = (data & 0x00020000) >> 17; + int zoomy = (data & 0x0001fc00) >> 10; + int y = (data & 0x000003ff); + + int bad_chunks = 0; + const int dimension = ((dblsize * 2) + 2); // 2 or 4 + const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16 + const u32 map_offset = tilenum << 2; + + zoomx += 1; + zoomy += 1; + + if (x > 713) x -= 1024; // 1024 x 512 + if (y < 117) y += 512; + + y = (-y & 0x3ff); + x -= x_offs; + y += y_offs; + if (flipy) y += (128 - zoomy); + + for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++) + { + const int j = sprite_chunk / dimension; // rows + const int k = sprite_chunk % dimension; // chunks per row + + int px = k; + int py = j; + // pick tiles back to front for x and y flips + if (flipx) px = dimension - 1 - k; + if (flipy) py = dimension - 1 - j; + + const u16 code = m_spritemap_rom[map_offset + px + (py << (dblsize + 1))]; + + if (code == 0xffff) + { + bad_chunks += 1; + continue; + } + + int curx = x + ((k * zoomx) / dimension); + int cury = y + ((j * zoomy) / dimension); + + const int zx = x + (((k + 1) * zoomx) / dimension) - curx; + const int zy = y + (((j + 1) * zoomy) / dimension) - cury; + + if (sprites_flipscreen) + { + /* -zx/y is there to fix zoomed sprite coords in screenflip. + drawgfxzoom does not know to draw from flip-side of sprites when + screen is flipped; so we must correct the coords ourselves. */ + + curx = 320 - curx - zx; + cury = 256 - cury - zy; + flipx = !flipx; + flipy = !flipy; + } + + m_sprite_ptr_pre->gfx = 0; + m_sprite_ptr_pre->code = code; + m_sprite_ptr_pre->color = color; + m_sprite_ptr_pre->flipx = !flipx; + m_sprite_ptr_pre->flipy = flipy; + m_sprite_ptr_pre->x = curx; + m_sprite_ptr_pre->y = cury; + m_sprite_ptr_pre->zoomx = zx << 12; + m_sprite_ptr_pre->zoomy = zy << 12; + m_sprite_ptr_pre->primask = priority; + + m_sprite_ptr_pre++; + } + if (bad_chunks) + LOGBADSPRITES("Sprite number %04x had %02x invalid chunks\n", tilenum, bad_chunks); + } +} + +void galastrm_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority) +{ + struct gs_tempsprite *sprite_ptr = m_sprite_ptr_pre; + + while (sprite_ptr != m_spritelist.get()) + { + sprite_ptr--; + + if ((priority != 0 && sprite_ptr->primask != 0) || + (priority == 0 && sprite_ptr->primask == 0)) + { + m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap, cliprect, + sprite_ptr->code, + sprite_ptr->color, + sprite_ptr->flipx, sprite_ptr->flipy, + sprite_ptr->x, sprite_ptr->y, + sprite_ptr->zoomx, sprite_ptr->zoomy, + screen.priority(), primasks[sprite_ptr->primask], 0); + } + } +} + +/************************************************************** + POLYGON RENDERER +**************************************************************/ + +void galastrm_renderer::tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid) +{ + u16 *const framebuffer = &m_screenbits.pix(scanline); + const s32 dudx = extent.param[0].dpdx; + const s32 dvdx = extent.param[1].dpdx; + + s32 u = extent.param[0].start; + s32 v = extent.param[1].start; + for (int x = extent.startx; x < extent.stopx; x++) + { + framebuffer[x] = object.texbase->pix(v >> 16, u >> 16); + u += dudx; + v += dvdx; + } +} + +void galastrm_renderer::tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip) +{ + struct polyVert + { + float x; + float y; +// float z; + } tmpz[4]; + + vertex_t vert[4]; + int rsx = m_state.m_tc0610_ctrl_reg[1][0]; + int rsy = m_state.m_tc0610_ctrl_reg[1][1]; + const int rzx = m_state.m_tc0610_ctrl_reg[1][2]; + const int rzy = m_state.m_tc0610_ctrl_reg[1][3]; + const int ryx = m_state.m_tc0610_ctrl_reg[1][5]; + const int ryy = m_state.m_tc0610_ctrl_reg[1][4]; + const int lx = srcbitmap.width(); + const int ly = srcbitmap.height(); + + int pxx = 0; + int pxy = 0; + int pyx = 0; + int pyy = 0; + int zx = 0; + int zy = 0; + + if (rzx != 0 || rzy != 0) + { + while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2)) + { + pxx += rzx; + pxy += rzy; + zx++; + } + while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2)) + { + pyy += rzx; + pyx += -rzy; + zy++; + } + } + float zsn = ((float)pyx / 4096.0f) / (float)(ly / 2); + float zcs = ((float)pxx / 4096.0f) / (float)(lx / 2); + + + if ((rsx == -240 && rsy == 1072) || !m_state.m_tc0610_ctrl_reg[1][7]) + { + m_state.m_rsxoffs = 0; + m_state.m_rsyoffs = 0; + } + else + { + if (rsx > m_state.m_rsxb && m_state.m_rsxb < 0 && rsx-m_state.m_rsxb > 0x8000) + { + if (m_state.m_rsxoffs == 0) + m_state.m_rsxoffs = -0x10000; + else + m_state.m_rsxoffs = 0; + } + if (rsx < m_state.m_rsxb && m_state.m_rsxb > 0 && m_state.m_rsxb-rsx > 0x8000) + { + if (m_state.m_rsxoffs == 0) + m_state.m_rsxoffs = 0x10000 - 1; + else + m_state.m_rsxoffs = 0; + } + if (rsy > m_state.m_rsyb && m_state.m_rsyb < 0 && rsy-m_state.m_rsyb > 0x8000) + { + if (m_state.m_rsyoffs == 0) + m_state.m_rsyoffs = -0x10000; + else + m_state.m_rsyoffs = 0; + } + if (rsy < m_state.m_rsyb && m_state.m_rsyb > 0 && m_state.m_rsyb-rsy > 0x8000) + { + if (m_state.m_rsyoffs == 0) + m_state.m_rsyoffs = 0x10000 - 1; + else + m_state.m_rsyoffs = 0; + } + } + m_state.m_rsxb = rsx; + m_state.m_rsyb = rsy; + if (m_state.m_rsxoffs) rsx += m_state.m_rsxoffs; + if (m_state.m_rsyoffs) rsy += m_state.m_rsyoffs; + if (rsx < -0x14000 || rsx >= 0x14000) m_state.m_rsxoffs = 0; + if (rsy < -0x14000 || rsy >= 0x14000) m_state.m_rsyoffs = 0; + + + pxx = 0; + pxy = 0; + pyx = 0; + pyy = 0; + int yx = 0; + //int yy = 0; + //float ssn = 0.0; + //float scs = 0.0; + //float ysn = 0.0; + //float ycs = 0.0; + + if (m_state.m_tc0610_ctrl_reg[1][7]) + { + if (ryx != 0 || ryy != 0) + { + while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2)) + { + pxx += ryx; + pxy += ryy; + yx++; + } + while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2)) + { + pyy += ryx; + pyx += -ryy; + //yy++; + } + if (yx >= 0.0) + { + yx = (int)((8.0 - log((double)yx) / log(2.0)) * 6.0); + //ysn = sin(DEGREE_TO_RADIAN(yx)); + //ycs = 1.0 - ysn*ysn; + } + } + + pxx = 0; + pxy = 0; + pyx = 0; + pyy = 0; + + if (rsx != 0 || rsy != 0) + { + while (sqrtf(powf((float)pxx / 65536.0f, 2.0) + powf((float)pxy / 65536.0f, 2.0f)) < (float)(lx / 2)) + { + pxx += rsx; + pxy += rsy; + } + while (sqrtf(powf((float)pyy / 65536.0f, 2.0f) + powf((float)pyx / 65536.0f, 2.0f)) < (float)(ly / 2)) + { + pyy += rsx; + pyx += -rsy; + } + } + //ssn = ((float)pxy/65536.0) / (float)(lx / 2); + //scs = ((float)pyy/65536.0) / (float)(ly / 2); + } + + { +// polyVert tmpz[4]; + tmpz[0].x = ((float)(-zx) * zcs) - ((float)(-zy) * zsn); + tmpz[0].y = ((float)(-zx) * zsn) + ((float)(-zy) * zcs); +// tmpz[0].z = 0.0; + tmpz[1].x = ((float)(-zx) * zcs) - ((float)(zy - 1) * zsn); + tmpz[1].y = ((float)(-zx) * zsn) + ((float)(zy - 1) * zcs); +// tmpz[1].z = 0.0; + tmpz[2].x = ((float)(zx - 1) * zcs) - ((float)(zy - 1) * zsn); + tmpz[2].y = ((float)(zx - 1) * zsn) + ((float)(zy - 1) * zcs); +// tmpz[2].z = 0.0; + tmpz[3].x = ((float)(zx - 1) * zcs) - ((float)(-zy) * zsn); + tmpz[3].y = ((float)(zx - 1) * zsn) + ((float)(-zy) * zcs); +// tmpz[3].z = 0.0; + + vert[0].x = tmpz[0].x + (float)(lx / 2); + vert[0].y = tmpz[0].y + (float)(ly / 2); + vert[1].x = tmpz[1].x + (float)(lx / 2); + vert[1].y = tmpz[1].y + (float)(ly / 2); + vert[2].x = tmpz[2].x + (float)(lx / 2); + vert[2].y = tmpz[2].y + (float)(ly / 2); + vert[3].x = tmpz[3].x + (float)(lx / 2); + vert[3].y = tmpz[3].y + (float)(ly / 2); + } + + vert[0].p[0] = 0.0; + vert[0].p[1] = 0.0; + vert[1].p[0] = 0.0; + vert[1].p[1] = (float)(ly - 1) * 65536.0f; + vert[2].p[0] = (float)(lx - 1) * 65536.0f; + vert[2].p[1] = (float)(ly - 1) * 65536.0f; + vert[3].p[0] = (float)(lx - 1) * 65536.0f; + vert[3].p[1] = 0.0; + + gs_poly_data& extra = object_data().next(); + extra.texbase = &srcbitmap; + + render_polygon<4, 2>(clip, render_delegate(&galastrm_renderer::tc0610_draw_scanline, this), vert); + wait(); +} + +/************************************************************** + SCREEN REFRESH +**************************************************************/ + +u32 galastrm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + u8 layer[5]; + u8 pivlayer[3]; + static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0}; + bitmap_ind8 &priority_bitmap = screen.priority(); + + rectangle clip(0, screen.width() -1, 0, screen.height() - 1); + + m_tc0100scn->tilemap_update(); + m_tc0480scp->tilemap_update(); + + const u16 priority = m_tc0480scp->get_bg_priority(); + layer[0] = (priority & 0xf000) >> 12; // tells us which bg layer is bottom + layer[1] = (priority & 0x0f00) >> 8; + layer[2] = (priority & 0x00f0) >> 4; + layer[3] = (priority & 0x000f) >> 0; // tells us which is top + layer[4] = 4; // text layer always over bg layers + + pivlayer[0] = m_tc0100scn->bottomlayer(); + pivlayer[1] = pivlayer[0] ^ 1; + pivlayer[2] = 2; + + bitmap.fill(0, cliprect); + priority_bitmap.fill(0, clip); + m_tmpbitmaps.fill(0, clip); + + m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[0], 0, 0); + m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[1], 0, 0); + +#if 0 + if (layer[0] == 0 && layer[1] == 3 && layer[2] == 2 && layer[3] == 1) + { + if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); + if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4); + if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); + if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4); + } + else + { + if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); + if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2); + if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); + if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8); + } + + if (layer[0] == 3 && layer[1] == 0 && layer[2] == 1 && layer[3] == 2) + { + for (int y = 0; y < priority_bitmap.height; y++) + { + for (int x = 0; x < priority_bitmap.width; x++) + { + u8 *pri = &priority_bitmap.pix(y, x); + if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x)) + *pri |= 0x04; + } + } + } + + draw_sprites_pre(machine(), 42 - X_OFFSET, -571 + Y_OFFSET); + draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1); + + copybitmap_trans(bitmap, m_polybitmap, 0, 0, 0, 0, cliprect, 0); + m_polybitmap->fill(0, clip); + tc0610_rotate_draw(machine(), m_polybitmap, m_tmpbitmaps, cliprect); + + priority_bitmap.fill(0, cliprect); + draw_sprites(screen, bitmap, cliprect, primasks, 0); + + if (!machine().input().code_pressed(KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); + if (!machine().input().code_pressed(KEYCODE_M)) m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0); + + + +#else + if (layer[0] == 0 && layer[1] == 3 && layer[2] == 2 && layer[3] == 1) + { + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4); + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4); + } + else + { + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2); + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); + m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8); + } + + if (layer[0] == 3 && layer[1] == 0 && layer[2] == 1 && layer[3] == 2) + { + for (int y=0; y < priority_bitmap.height(); y++) + { + for (int x=0; x < priority_bitmap.width(); x++) + { + u8 *pri = &priority_bitmap.pix(y, x); + if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x)) + *pri |= 0x04; + } + } + } + + draw_sprites_pre(42 - X_OFFSET, -571 + Y_OFFSET); + draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1); + + copybitmap_trans(bitmap, m_poly->screenbits(), 0, 0, 0, 0, cliprect, 0); + m_poly->screenbits().fill(0, clip); + m_poly->tc0610_rotate_draw(m_tmpbitmaps, cliprect); + + priority_bitmap.fill(0, cliprect); + draw_sprites(screen, bitmap, cliprect, primasks, 0); + + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); + m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0); +#endif + + return 0; +} + + +// machine + /*********************************************************************/ INTERRUPT_GEN_MEMBER(galastrm_state::interrupt) @@ -93,18 +742,18 @@ void galastrm_state::coin_word_w(u8 data) void galastrm_state::main_map(address_map &map) { map(0x000000, 0x0fffff).rom(); - map(0x200000, 0x21ffff).ram(); /* main CPU ram */ - map(0x300000, 0x303fff).ram().share("spriteram"); + map(0x200000, 0x21ffff).ram(); // main RAM + map(0x300000, 0x303fff).ram().share(m_spriteram); map(0x400000, 0x400007).rw("tc0510nio", FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write)); map(0x40fff0, 0x40fff3).nopw(); map(0x500000, 0x500007).rw("adc", FUNC(adc0808_device::data_r), FUNC(adc0808_device::address_offset_start_w)).umask32(0xffffffff); - map(0x600000, 0x6007ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); /* Sound shared ram */ - map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); /* tilemaps */ + map(0x600000, 0x6007ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); // Sound shared RAM + map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); // tilemaps map(0x830000, 0x83002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w)); - map(0x900000, 0x900003).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_rbswap_word_w)); /* TC0110PCR */ - map(0xb00000, 0xb00003).w(FUNC(galastrm_state::tc0610_w<0>)); /* TC0610 */ + map(0x900000, 0x900003).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_rbswap_word_w)); + map(0xb00000, 0xb00003).w(FUNC(galastrm_state::tc0610_w<0>)); map(0xc00000, 0xc00003).w(FUNC(galastrm_state::tc0610_w<1>)); - map(0xd00000, 0xd0ffff).rw(m_tc0100scn, FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* piv tilemaps */ + map(0xd00000, 0xd0ffff).rw(m_tc0100scn, FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); // piv tilemaps map(0xd20000, 0xd2000f).rw(m_tc0100scn, FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w)); } @@ -124,7 +773,7 @@ static INPUT_PORTS_START( galastrm ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN1") -// PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) /* Freeze input */ +// PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) // Freeze input PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -157,17 +806,17 @@ INPUT_PORTS_END static const gfx_layout tile16x16_layout = { - 16,16, /* 16*16 sprites */ + 16,16, // 16*16 sprites RGN_FRAC(1,1), - 4, /* 4 bits per pixel */ + 4, // 4 bits per pixel { STEP4(0,16) }, { STEP16(0,1) }, { STEP16(0,16*4) }, - 64*16 /* every sprite takes 128 consecutive bytes */ + 64*16 // every sprite takes 128 consecutive bytes }; static GFXDECODE_START( gfx_galastrm ) - GFXDECODE_ENTRY( "sprites", 0x0, tile16x16_layout, 0, 4096/16 ) + GFXDECODE_ENTRY( "sprites", 0x0, tile16x16_layout, 0, 4096 / 16 ) GFXDECODE_END @@ -179,14 +828,14 @@ GFXDECODE_END void galastrm_state::galastrm(machine_config &config) { - /* basic machine hardware */ - M68EC020(config, m_maincpu, 16000000); /* 16 MHz */ + // basic machine hardware + M68EC020(config, m_maincpu, 32_MHz_XTAL / 2); // 16 MHz m_maincpu->set_addrmap(AS_PROGRAM, &galastrm_state::main_map); - m_maincpu->set_vblank_int("screen", FUNC(galastrm_state::interrupt)); /* VBL */ + m_maincpu->set_vblank_int("screen", FUNC(galastrm_state::interrupt)); // VBL EEPROM_93C46_16BIT(config, "eeprom"); - adc0809_device &adc(ADC0809(config, "adc", 500000)); // unknown clock + adc0809_device &adc(ADC0809(config, "adc", 500'000)); // unknown clock adc.eoc_ff_callback().set_inputline("maincpu", 6); adc.in_callback<0>().set_ioport("STICKX"); adc.in_callback<1>().set_ioport("STICKY"); @@ -200,7 +849,7 @@ void galastrm_state::galastrm(machine_config &config) tc0510nio.write_4_callback().set(FUNC(galastrm_state::coin_word_w)); tc0510nio.read_7_callback().set_ioport("IN2"); - /* video hardware */ + // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); @@ -221,7 +870,7 @@ void galastrm_state::galastrm(machine_config &config) TC0110PCR(config, m_tc0110pcr, 0); - /* sound hardware */ + // sound hardware SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -233,7 +882,7 @@ void galastrm_state::galastrm(machine_config &config) /***************************************************************************/ ROM_START( galastrm ) - ROM_REGION( 0x100000, "maincpu", 0 ) /* for 68020 code (CPU A) */ + ROM_REGION( 0x100000, "maincpu", 0 ) // for 68020 code (CPU A) ROM_LOAD32_BYTE( "c99_15.ic105", 0x00000, 0x40000, CRC(7eae8efd) SHA1(6bbb3da697dfcd93337b53895678e2a4ff2de457) ) ROM_LOAD32_BYTE( "c99_12.ic102", 0x00001, 0x40000, CRC(e059d1ee) SHA1(560951f95f270f0559b5289dda7f4ba74538cfcb) ) ROM_LOAD32_BYTE( "c99_13.ic103", 0x00002, 0x40000, CRC(885fcb35) SHA1(be10e109c461c1f776e98efa1b2a4d588aa0c41c) ) @@ -243,23 +892,23 @@ ROM_START( galastrm ) ROM_LOAD16_BYTE( "c99_23.ic8", 0x100000, 0x20000, CRC(5718ee92) SHA1(33cfa60c5bceb1525498f27b598067d2dc620431) ) ROM_LOAD16_BYTE( "c99_22.ic7", 0x100001, 0x20000, CRC(b90f7c42) SHA1(e2fa9ee10ad61ae1a672c3357c0072b79ec7fbcb) ) - ROM_REGION( 0x100, "tc0100scn", ROMREGION_ERASE00 ) // no roms for tc0100scn, dummy + ROM_REGION( 0x100, "tc0100scn", ROMREGION_ERASE00 ) // no ROMs for tc0100scn, dummy - ROM_REGION( 0x200000, "tc0480scp", 0 ) - ROM_LOAD32_WORD( "c99-05.ic1", 0x000000, 0x100000, CRC(a91ffba4) SHA1(467af9646ddad5fbb520b6bc13517ed4deacf479) ) /* SCR 16x16 tiles */ + ROM_REGION( 0x200000, "tc0480scp", 0 ) // SCR 16x16 tiles + ROM_LOAD32_WORD( "c99-05.ic1", 0x000000, 0x100000, CRC(a91ffba4) SHA1(467af9646ddad5fbb520b6bc13517ed4deacf479) ) ROM_LOAD32_WORD( "c99-06.ic2", 0x000002, 0x100000, CRC(812ed3ae) SHA1(775904dd42643d0e3a30890590d5f8eac1fe78db) ) - ROM_REGION( 0x400000, "sprites", 0 ) - ROM_LOAD64_WORD_SWAP( "c99-02.ic50", 0x000000, 0x100000, CRC(81e9fc6f) SHA1(4495a7d130b755b5a48eaa814d884d6bb8243bcb) ) /* OBJ 16x16 tiles */ + ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles + ROM_LOAD64_WORD_SWAP( "c99-02.ic50", 0x000000, 0x100000, CRC(81e9fc6f) SHA1(4495a7d130b755b5a48eaa814d884d6bb8243bcb) ) ROM_LOAD64_WORD_SWAP( "c99-01.ic51", 0x000002, 0x100000, CRC(9dda1267) SHA1(c639ba064496dcadf5f1e55332a12bb442e9dc86) ) ROM_LOAD64_WORD_SWAP( "c99-04.ic66", 0x000004, 0x100000, CRC(a681760f) SHA1(23d4fc7eb778c8a25c4bc7cee1d0c8cdd828a996) ) ROM_LOAD64_WORD_SWAP( "c99-03.ic67", 0x000006, 0x100000, CRC(a2807a27) SHA1(977e395ea2ab2fb82807d3cf5fe5f1dbbde99da0) ) - ROM_REGION16_LE( 0x80000, "sprmaprom", 0 ) - ROM_LOAD16_WORD( "c99-11.ic90", 0x00000, 0x80000, CRC(26a6926c) SHA1(918860e2829131e9ecfe983b2ae3e49e1c9ecd72) ) /* STY, spritemap */ + ROM_REGION16_LE( 0x80000, "sprmaprom", 0 ) // STY + ROM_LOAD16_WORD( "c99-11.ic90", 0x00000, 0x80000, CRC(26a6926c) SHA1(918860e2829131e9ecfe983b2ae3e49e1c9ecd72) ) ROM_REGION16_BE( 0x1000000, "taito_en:ensoniq", ROMREGION_ERASE00 ) - ROM_LOAD16_BYTE( "c99-08.ic3", 0x000000, 0x100000, CRC(fedb4187) SHA1(83563e4af795a0dfeb261a62c31b6fed72f45a4d) ) /* Ensoniq samples */ + ROM_LOAD16_BYTE( "c99-08.ic3", 0x000000, 0x100000, CRC(fedb4187) SHA1(83563e4af795a0dfeb261a62c31b6fed72f45a4d) ) ROM_LOAD16_BYTE( "c99-09.ic4", 0x200000, 0x100000, CRC(ba70b86b) SHA1(ffbb9547d6b6e47a3ef23206b5f40c57f3ea7619) ) ROM_LOAD16_BYTE( "c99-10.ic5", 0x400000, 0x100000, CRC(da016f1e) SHA1(581ef158c6f6576618dd75429b1d3aa92cd3581d) ) ROM_LOAD16_BYTE( "c99-07.ic2", 0x680000, 0x040000, CRC(4cc3136f) SHA1(d9d7556bbe6af161fa0651b1fbd72e7dbf0a8e82) ) @@ -271,5 +920,7 @@ ROM_START( galastrm ) ROM_LOAD16_WORD( "eeprom-galastrm.bin", 0x0000, 0x0080, CRC(94efa7a6) SHA1(5870b988cb364065e8bd779efbdadca8d3ffc17c) ) ROM_END +} // anonymous namespace + GAME( 1992, galastrm, 0, galastrm, galastrm, galastrm_state, empty_init, ROT0, "Taito Corporation", "Galactic Storm (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/taito/galastrm.h b/src/mame/taito/galastrm.h deleted file mode 100644 index 7b1813ec975..00000000000 --- a/src/mame/taito/galastrm.h +++ /dev/null @@ -1,111 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Hau -#ifndef MAME_INCLUDES_GALASTRM_H -#define MAME_INCLUDES_GALASTRM_H - -#pragma once - -#include "machine/eepromser.h" - -#include "video/poly.h" -#include "tc0100scn.h" -#include "tc0110pcr.h" -#include "tc0480scp.h" - -#include "emupal.h" -#include "screen.h" - - -class galastrm_state; - -struct gs_poly_data -{ - bitmap_ind16* texbase = nullptr; -}; - -class galastrm_renderer : public poly_manager -{ -public: - galastrm_renderer(galastrm_state &state); - - void tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid); - void tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip); - - bitmap_ind16 &screenbits() { return m_screenbits; } - -private: - galastrm_state& m_state; - bitmap_ind16 m_screenbits; -}; - - -class galastrm_state : public driver_device -{ - friend class galastrm_renderer; -public: - galastrm_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_spriteram(*this,"spriteram"), - m_spritemap_rom(*this, "sprmaprom"), - m_maincpu(*this, "maincpu"), - m_eeprom(*this, "eeprom"), - m_tc0100scn(*this, "tc0100scn"), - m_tc0110pcr(*this, "tc0110pcr"), - m_tc0480scp(*this, "tc0480scp"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen") - { } - - void galastrm(machine_config &config); - DECLARE_READ_LINE_MEMBER(frame_counter_r); - -protected: - virtual void video_start() override; - -private: - required_shared_ptr m_spriteram; - - required_region_ptr m_spritemap_rom; - - required_device m_maincpu; - required_device m_eeprom; - required_device m_tc0100scn; - required_device m_tc0110pcr; - required_device m_tc0480scp; - required_device m_gfxdecode; - required_device m_screen; - - struct gs_tempsprite - { - u8 gfx = 0U; - u32 code = 0U, color = 0U; - bool flipx = false, flipy = false; - int x = 0, y = 0; - int zoomx = 0, zoomy = 0; - u32 primask = 0U; - }; - - u16 m_frame_counter = 0U; - int m_tc0610_addr[2]{}; - s16 m_tc0610_ctrl_reg[2][8]{}; - std::unique_ptr m_spritelist{}; - struct gs_tempsprite *m_sprite_ptr_pre{}; - bitmap_ind16 m_tmpbitmaps{}; - std::unique_ptr m_poly{}; - - int m_rsxb = 0; - int m_rsyb = 0; - int m_rsxoffs = 0; - int m_rsyoffs = 0; - - template void tc0610_w(offs_t offset, u16 data); - void coin_word_w(u8 data); - u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(interrupt); - void draw_sprites_pre(int x_offs, int y_offs); - void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority); - - void main_map(address_map &map); -}; - -#endif // MAME_INCLUDES_GALASTRM_H diff --git a/src/mame/taito/galastrm_v.cpp b/src/mame/taito/galastrm_v.cpp deleted file mode 100644 index 2b8fbfaa9cb..00000000000 --- a/src/mame/taito/galastrm_v.cpp +++ /dev/null @@ -1,535 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Hau -#include "emu.h" -#include "galastrm.h" - -#define X_OFFSET 96 -#define Y_OFFSET 60 - - -galastrm_renderer::galastrm_renderer(galastrm_state& state) - : poly_manager(state.machine()) - , m_state(state) - , m_screenbits(state.m_screen->width(), state.m_screen->height()) -{ -} - - -/******************************************************************/ - -void galastrm_state::video_start() -{ - m_spritelist = std::make_unique(0x4000); - - m_poly = std::make_unique(*this); - - m_screen->register_screen_bitmap(m_tmpbitmaps); - m_screen->register_screen_bitmap(m_poly->screenbits()); - - save_item(NAME(m_rsxb)); - save_item(NAME(m_rsyb)); - save_item(NAME(m_rsxoffs)); - save_item(NAME(m_rsyoffs)); - save_item(NAME(m_frame_counter)); - save_item(NAME(m_tc0610_addr)); - save_item(NAME(m_tc0610_ctrl_reg)); -} - - -/************************************************************ - SPRITE DRAW ROUTINES - -We draw a series of small tiles ("chunks") together to -create each big sprite. The spritemap rom provides the lookup -table for this. The game hardware looks up 16x16 sprite chunks -from the spritemap rom, creating a 64x64 sprite like this: - - 0 1 2 3 - 4 5 6 7 - 8 9 10 11 - 12 13 14 15 - -(where the number is the word offset into the spritemap rom). -It can also create 32x32 sprites. - -NB: unused portions of the spritemap rom contain hex FF's. -It is a useful coding check to warn in the log if these -are being accessed. [They can be inadvertently while -spriteram is being tested, take no notice of that.] - -Heavy use is made of sprite zooming. - - *** - - Sprite table layout (4 long words per entry) - - ------------------------------------------ - 0 | ........ x....... ........ ........ | Flip X - 0 | ........ .xxxxxxx ........ ........ | ZoomX - 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile - | | - 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*] - 2 | ........ ......xx xxxxxx.. ........ | Palette bank - 2 | ........ ........ ......xx xxxxxxxx | X position - | | - 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64) - 3 | ........ ......x. ........ ........ | Flip Y - 3 | ........ .......x xxxxxx.. ........ | ZoomY - 3 | ........ ........ ......xx xxxxxxxx | Y position - ------------------------------------------ - - [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???] - -********************************************************/ - -void galastrm_state::draw_sprites_pre(int x_offs, int y_offs) -{ - int sprites_flipscreen = 0; - - /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list - while processing sprite ram and then draw them all at the end */ - m_sprite_ptr_pre = m_spritelist.get(); - - for (int offs = (m_spriteram.bytes()/4-4);offs >= 0;offs -= 4) - { - u32 data = m_spriteram[offs+0]; - int flipx = (data & 0x00800000) >> 23; - int zoomx = (data & 0x007f0000) >> 16; - const u32 tilenum = (data & 0x00007fff); - - if (!tilenum) continue; - - data = m_spriteram[offs+2]; - const int priority = (data & 0x000c0000) >> 18; - int color = (data & 0x0003fc00) >> 10; - int x = (data & 0x000003ff); - - data = m_spriteram[offs+3]; - const int dblsize = (data & 0x00040000) >> 18; - int flipy = (data & 0x00020000) >> 17; - int zoomy = (data & 0x0001fc00) >> 10; - int y = (data & 0x000003ff); - - int bad_chunks = 0; - const int dimension = ((dblsize * 2) + 2); // 2 or 4 - const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16 - const u32 map_offset = tilenum << 2; - - zoomx += 1; - zoomy += 1; - - if (x > 713) x -= 1024; /* 1024x512 */ - if (y < 117) y += 512; - - y = (-y & 0x3ff); - x -= x_offs; - y += y_offs; - if (flipy) y += (128 - zoomy); - - for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++) - { - const int j = sprite_chunk / dimension; /* rows */ - const int k = sprite_chunk % dimension; /* chunks per row */ - - int px = k; - int py = j; - /* pick tiles back to front for x and y flips */ - if (flipx) px = dimension - 1 - k; - if (flipy) py = dimension - 1 - j; - - const u16 code = m_spritemap_rom[map_offset + px + (py << (dblsize + 1))]; - - if (code == 0xffff) - { - bad_chunks += 1; - continue; - } - - int curx = x + ((k * zoomx) / dimension); - int cury = y + ((j * zoomy) / dimension); - - const int zx = x + (((k + 1) * zoomx) / dimension) - curx; - const int zy = y + (((j + 1) * zoomy) / dimension) - cury; - - if (sprites_flipscreen) - { - /* -zx/y is there to fix zoomed sprite coords in screenflip. - drawgfxzoom does not know to draw from flip-side of sprites when - screen is flipped; so we must correct the coords ourselves. */ - - curx = 320 - curx - zx; - cury = 256 - cury - zy; - flipx = !flipx; - flipy = !flipy; - } - - m_sprite_ptr_pre->gfx = 0; - m_sprite_ptr_pre->code = code; - m_sprite_ptr_pre->color = color; - m_sprite_ptr_pre->flipx = !flipx; - m_sprite_ptr_pre->flipy = flipy; - m_sprite_ptr_pre->x = curx; - m_sprite_ptr_pre->y = cury; - m_sprite_ptr_pre->zoomx = zx << 12; - m_sprite_ptr_pre->zoomy = zy << 12; - m_sprite_ptr_pre->primask = priority; - - m_sprite_ptr_pre++; - } - if (bad_chunks) - logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks); - } -} - -void galastrm_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int priority) -{ - struct gs_tempsprite *sprite_ptr = m_sprite_ptr_pre; - - while (sprite_ptr != m_spritelist.get()) - { - sprite_ptr--; - - if ((priority != 0 && sprite_ptr->primask != 0) || - (priority == 0 && sprite_ptr->primask == 0)) - { - m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap,cliprect, - sprite_ptr->code, - sprite_ptr->color, - sprite_ptr->flipx,sprite_ptr->flipy, - sprite_ptr->x,sprite_ptr->y, - sprite_ptr->zoomx,sprite_ptr->zoomy, - screen.priority(),primasks[sprite_ptr->primask],0); - } - } -} - -/************************************************************** - POLYGON RENDERER -**************************************************************/ - -void galastrm_renderer::tc0610_draw_scanline(s32 scanline, const extent_t& extent, const gs_poly_data& object, int threadid) -{ - u16 *const framebuffer = &m_screenbits.pix(scanline); - const s32 dudx = extent.param[0].dpdx; - const s32 dvdx = extent.param[1].dpdx; - - s32 u = extent.param[0].start; - s32 v = extent.param[1].start; - for (int x = extent.startx; x < extent.stopx; x++) - { - framebuffer[x] = object.texbase->pix(v >> 16, u >> 16); - u += dudx; - v += dvdx; - } -} - -void galastrm_renderer::tc0610_rotate_draw(bitmap_ind16 &srcbitmap, const rectangle &clip) -{ - struct polyVert - { - float x; - float y; -// float z; - } tmpz[4]; - - vertex_t vert[4]; - int rsx = m_state.m_tc0610_ctrl_reg[1][0]; - int rsy = m_state.m_tc0610_ctrl_reg[1][1]; - const int rzx = m_state.m_tc0610_ctrl_reg[1][2]; - const int rzy = m_state.m_tc0610_ctrl_reg[1][3]; - const int ryx = m_state.m_tc0610_ctrl_reg[1][5]; - const int ryy = m_state.m_tc0610_ctrl_reg[1][4]; - const int lx = srcbitmap.width(); - const int ly = srcbitmap.height(); - - int pxx = 0; - int pxy = 0; - int pyx = 0; - int pyy = 0; - int zx = 0; - int zy = 0; - - if (rzx != 0 || rzy != 0) - { - while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2)) - { - pxx += rzx; - pxy += rzy; - zx++; - } - while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2)) - { - pyy += rzx; - pyx += -rzy; - zy++; - } - } - float zsn = ((float)pyx / 4096.0f) / (float)(ly / 2); - float zcs = ((float)pxx / 4096.0f) / (float)(lx / 2); - - - if ((rsx == -240 && rsy == 1072) || !m_state.m_tc0610_ctrl_reg[1][7]) - { - m_state.m_rsxoffs = 0; - m_state.m_rsyoffs = 0; - } - else - { - if (rsx > m_state.m_rsxb && m_state.m_rsxb < 0 && rsx-m_state.m_rsxb > 0x8000) - { - if (m_state.m_rsxoffs == 0) - m_state.m_rsxoffs = -0x10000; - else - m_state.m_rsxoffs = 0; - } - if (rsx < m_state.m_rsxb && m_state.m_rsxb > 0 && m_state.m_rsxb-rsx > 0x8000) - { - if (m_state.m_rsxoffs == 0) - m_state.m_rsxoffs = 0x10000 - 1; - else - m_state.m_rsxoffs = 0; - } - if (rsy > m_state.m_rsyb && m_state.m_rsyb < 0 && rsy-m_state.m_rsyb > 0x8000) - { - if (m_state.m_rsyoffs == 0) - m_state.m_rsyoffs = -0x10000; - else - m_state.m_rsyoffs = 0; - } - if (rsy < m_state.m_rsyb && m_state.m_rsyb > 0 && m_state.m_rsyb-rsy > 0x8000) - { - if (m_state.m_rsyoffs == 0) - m_state.m_rsyoffs = 0x10000 - 1; - else - m_state.m_rsyoffs = 0; - } - } - m_state.m_rsxb = rsx; - m_state.m_rsyb = rsy; - if (m_state.m_rsxoffs) rsx += m_state.m_rsxoffs; - if (m_state.m_rsyoffs) rsy += m_state.m_rsyoffs; - if (rsx < -0x14000 || rsx >= 0x14000) m_state.m_rsxoffs = 0; - if (rsy < -0x14000 || rsy >= 0x14000) m_state.m_rsyoffs = 0; - - - pxx = 0; - pxy = 0; - pyx = 0; - pyy = 0; - int yx = 0; - //int yy = 0; - //float ssn = 0.0; - //float scs = 0.0; - //float ysn = 0.0; - //float ycs = 0.0; - - if (m_state.m_tc0610_ctrl_reg[1][7]) - { - if (ryx != 0 || ryy != 0) - { - while (sqrtf(powf((float)pxx / 4096.0f, 2.0f) + powf((float)pxy / 4096.0f, 2.0f)) < (float)(lx / 2)) - { - pxx += ryx; - pxy += ryy; - yx++; - } - while (sqrtf(powf((float)pyy / 4096.0f, 2.0f) + powf((float)pyx / 4096.0f, 2.0f)) < (float)(ly / 2)) - { - pyy += ryx; - pyx += -ryy; - //yy++; - } - if (yx >= 0.0) - { - yx = (int)((8.0 - log((double)yx) / log(2.0)) * 6.0); - //ysn = sin(DEGREE_TO_RADIAN(yx)); - //ycs = 1.0 - ysn*ysn; - } - } - - pxx = 0; - pxy = 0; - pyx = 0; - pyy = 0; - - if (rsx != 0 || rsy != 0) - { - while (sqrtf(powf((float)pxx / 65536.0f, 2.0) + powf((float)pxy / 65536.0f, 2.0f)) < (float)(lx / 2)) - { - pxx += rsx; - pxy += rsy; - } - while (sqrtf(powf((float)pyy / 65536.0f, 2.0f) + powf((float)pyx / 65536.0f, 2.0f)) < (float)(ly / 2)) - { - pyy += rsx; - pyx += -rsy; - } - } - //ssn = ((float)pxy/65536.0) / (float)(lx / 2); - //scs = ((float)pyy/65536.0) / (float)(ly / 2); - } - - { -// polyVert tmpz[4]; - tmpz[0].x = ((float)(-zx) * zcs) - ((float)(-zy) * zsn); - tmpz[0].y = ((float)(-zx) * zsn) + ((float)(-zy) * zcs); -// tmpz[0].z = 0.0; - tmpz[1].x = ((float)(-zx) * zcs) - ((float)(zy - 1) * zsn); - tmpz[1].y = ((float)(-zx) * zsn) + ((float)(zy - 1) * zcs); -// tmpz[1].z = 0.0; - tmpz[2].x = ((float)(zx - 1) * zcs) - ((float)(zy - 1) * zsn); - tmpz[2].y = ((float)(zx - 1) * zsn) + ((float)(zy - 1) * zcs); -// tmpz[2].z = 0.0; - tmpz[3].x = ((float)(zx - 1) * zcs) - ((float)(-zy) * zsn); - tmpz[3].y = ((float)(zx - 1) * zsn) + ((float)(-zy) * zcs); -// tmpz[3].z = 0.0; - - vert[0].x = tmpz[0].x + (float)(lx / 2); - vert[0].y = tmpz[0].y + (float)(ly / 2); - vert[1].x = tmpz[1].x + (float)(lx / 2); - vert[1].y = tmpz[1].y + (float)(ly / 2); - vert[2].x = tmpz[2].x + (float)(lx / 2); - vert[2].y = tmpz[2].y + (float)(ly / 2); - vert[3].x = tmpz[3].x + (float)(lx / 2); - vert[3].y = tmpz[3].y + (float)(ly / 2); - } - - vert[0].p[0] = 0.0; - vert[0].p[1] = 0.0; - vert[1].p[0] = 0.0; - vert[1].p[1] = (float)(ly - 1) * 65536.0f; - vert[2].p[0] = (float)(lx - 1) * 65536.0f; - vert[2].p[1] = (float)(ly - 1) * 65536.0f; - vert[3].p[0] = (float)(lx - 1) * 65536.0f; - vert[3].p[1] = 0.0; - - gs_poly_data& extra = object_data().next(); - extra.texbase = &srcbitmap; - - render_polygon<4, 2>(clip, render_delegate(&galastrm_renderer::tc0610_draw_scanline, this), vert); - wait(); -} - -/************************************************************** - SCREEN REFRESH -**************************************************************/ - -u32 galastrm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - u8 layer[5]; - u8 pivlayer[3]; - static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0}; - bitmap_ind8 &priority_bitmap = screen.priority(); - - rectangle clip(0, screen.width() -1, 0, screen.height() - 1); - - m_tc0100scn->tilemap_update(); - m_tc0480scp->tilemap_update(); - - const u16 priority = m_tc0480scp->get_bg_priority(); - layer[0] = (priority & 0xf000) >> 12; /* tells us which bg layer is bottom */ - layer[1] = (priority & 0x0f00) >> 8; - layer[2] = (priority & 0x00f0) >> 4; - layer[3] = (priority & 0x000f) >> 0; /* tells us which is top */ - layer[4] = 4; /* text layer always over bg layers */ - - pivlayer[0] = m_tc0100scn->bottomlayer(); - pivlayer[1] = pivlayer[0] ^ 1; - pivlayer[2] = 2; - - bitmap.fill(0, cliprect); - priority_bitmap.fill(0, clip); - m_tmpbitmaps.fill(0, clip); - - m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[0], 0, 0); - m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[1], 0, 0); - -#if 0 - if (layer[0]==0 && layer[1]==3 && layer[2]==2 && layer[3]==1) - { - if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); - if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4); - if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); - if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4); - } - else - { - if (!machine().input().code_pressed(KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); - if (!machine().input().code_pressed(KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2); - if (!machine().input().code_pressed(KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); - if (!machine().input().code_pressed(KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8); - } - - if (layer[0]==3 && layer[1]==0 && layer[2]==1 && layer[3]==2) - { - for (int y = 0; y < priority_bitmap.height; y++) - { - for (int x = 0; x < priority_bitmap.width; x++) - { - u8 *pri = &priority_bitmap.pix(y, x); - if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x)) - *pri |= 0x04; - } - } - } - - draw_sprites_pre(machine(), 42-X_OFFSET, -571+Y_OFFSET); - draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1); - - copybitmap_trans(bitmap, m_polybitmap, 0,0, 0,0, cliprect, 0); - m_polybitmap->fill(0, clip); - tc0610_rotate_draw(machine(), m_polybitmap, m_tmpbitmaps, cliprect); - - priority_bitmap.fill(0, cliprect); - draw_sprites(screen, bitmap, cliprect, primasks, 0); - - if (!machine().input().code_pressed(KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); - if (!machine().input().code_pressed(KEYCODE_M)) m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0); - - - -#else - if (layer[0] == 0 && layer[1] == 3 && layer[2] == 2 && layer[3] == 1) - { - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 4); - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 4); - } - else - { - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[0], 0, 1); - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[1], 0, 2); - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[2], 0, 4); - m_tc0480scp->tilemap_draw(screen, m_tmpbitmaps, clip, layer[3], 0, 8); - } - - if (layer[0] == 3 && layer[1] == 0 && layer[2] == 1 && layer[3] == 2) - { - for (int y=0; y < priority_bitmap.height(); y++) - { - for (int x=0; x < priority_bitmap.width(); x++) - { - u8 *pri = &priority_bitmap.pix(y, x); - if (!(*pri & 0x02) && m_tmpbitmaps.pix(y, x)) - *pri |= 0x04; - } - } - } - - draw_sprites_pre(42 - X_OFFSET, -571 + Y_OFFSET); - draw_sprites(screen, m_tmpbitmaps, clip, primasks, 1); - - copybitmap_trans(bitmap, m_poly->screenbits(), 0,0, 0,0, cliprect, 0); - m_poly->screenbits().fill(0, clip); - m_poly->tc0610_rotate_draw(m_tmpbitmaps, cliprect); - - priority_bitmap.fill(0, cliprect); - draw_sprites(screen, bitmap, cliprect, primasks, 0); - - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); - m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, pivlayer[2], 0, 0); -#endif - - return 0; -} diff --git a/src/mame/taito/groundfx.cpp b/src/mame/taito/groundfx.cpp index 2c0860b91cb..12e226589a7 100644 --- a/src/mame/taito/groundfx.cpp +++ b/src/mame/taito/groundfx.cpp @@ -219,17 +219,17 @@ void groundfx_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, c for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4) { - u32 data = m_spriteram[offs+0]; + u32 data = m_spriteram[offs + 0]; int flipx = (data & 0x00800000) >> 23; int zoomx = (data & 0x007f0000) >> 16; const u32 tilenum = (data & 0x00007fff); - data = m_spriteram[offs+2]; + data = m_spriteram[offs + 2]; const int priority = (data & 0x000c0000) >> 18; u32 color = (data & 0x0003fc00) >> 10; int x = (data & 0x000003ff); - data = m_spriteram[offs+3]; + data = m_spriteram[offs + 3]; const int dblsize = (data & 0x00040000) >> 18; int flipy = (data & 0x00020000) >> 17; int zoomy = (data & 0x0001fc00) >> 10; diff --git a/src/mame/taito/gunbustr.cpp b/src/mame/taito/gunbustr.cpp index 54b47927047..0208f62c392 100644 --- a/src/mame/taito/gunbustr.cpp +++ b/src/mame/taito/gunbustr.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Bryan McPhail, David Graves +// copyright-holders: Bryan McPhail, David Graves + /**************************************************************************** Gunbuster (c) 1992 Taito @@ -22,9 +23,9 @@ Gunbuster uses a slightly enhanced sprite system from the one in Taito Z games. - The key feature remains the use of a sprite map rom which allows + The key feature remains the use of a sprite map ROM which allows the sprite hardware to create many large zoomed sprites on screen - while minimizing the main cpu load. + while minimizing the main CPU load. This feature makes the SZ system complementary to the F3 system which, owing to its F2 sprite hardware, is not very well suited to @@ -44,19 +45,340 @@ ***************************************************************************/ #include "emu.h" -#include "gunbustr.h" #include "taito_en.h" #include "taitoio.h" +#include "tc0480scp.h" #include "cpu/m68000/m68000.h" #include "machine/eepromser.h" #include "sound/es5506.h" +#include "emupal.h" #include "screen.h" #include "speaker.h" +// configurable logging +#define LOG_BADSPRITES (1U << 1) + +//#define VERBOSE (LOG_GENERAL | LOG_BADSPRITES) + +#include "logmacro.h" + +#define LOGBADSPRITES(...) LOGMASKED(LOG_BADSPRITES, __VA_ARGS__) + + +namespace { + +class gunbustr_state : public driver_device +{ +public: + gunbustr_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this,"maincpu"), + m_tc0480scp(*this, "tc0480scp"), + m_ram(*this,"ram"), + m_spriteram(*this,"spriteram"), + m_eeprom(*this, "eeprom"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette"), + m_spritemap(*this, "spritemap"), + m_io_light_x(*this, "LIGHT%u_X", 0U), + m_io_light_y(*this, "LIGHT%u_Y", 0U), + m_gun_recoil_pl(*this, "Player%u_Gun_Recoil", 1U), + m_hit_lamp(*this, "Hit_lamp") + + { + m_coin_lockout = true; + } + + void gunbustr(machine_config &config); + + void init_gunbustrj(); + void init_gunbustr(); + +protected: + virtual void video_start() override; + +private: + void prg_map(address_map &map); + + TIMER_CALLBACK_MEMBER(trigger_irq5); + + void motor_control_w(u32 data); + u32 gun_r(); + void gun_w(u32 data); + u32 main_cycle_r(); + void coin_word_w(u8 data); + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(gunbustr_interrupt); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int x_offs, int y_offs); + + required_device m_maincpu; + required_device m_tc0480scp; + required_shared_ptr m_ram; + required_shared_ptr m_spriteram; + required_device m_eeprom; + required_device m_gfxdecode; + required_device m_palette; + required_region_ptr m_spritemap; + + required_ioport_array<2> m_io_light_x; + required_ioport_array<2> m_io_light_y; + output_finder<2> m_gun_recoil_pl; + output_finder<> m_hit_lamp; + + struct gb_tempsprite + { + int gfx = 0; + int code = 0, color = 0; + int flipx,flipy = 0; + int x = 0, y = 0; + int zoomx = 0, zoomy = 0; + int primask = 0; + }; + + bool m_coin_lockout; + std::unique_ptr m_spritelist{}; + emu_timer *m_interrupt5_timer = nullptr; +}; + + +// video + +/************************************************************/ + +void gunbustr_state::video_start() +{ + m_spritelist = std::make_unique(0x4000); + + m_gun_recoil_pl.resolve(); + m_hit_lamp.resolve(); +} + +/************************************************************ + SPRITE DRAW ROUTINES + +We draw a series of small tiles ("chunks") together to +create each big sprite. The spritemap ROM provides the lookup +table for this. The game hardware looks up 16x16 sprite chunks +from the spritemap ROM, creating a 64x64 sprite like this: + + 0 1 2 3 + 4 5 6 7 + 8 9 10 11 + 12 13 14 15 + +(where the number is the word offset into the spritemap ROM). +It can also create 32x32 sprites. + +NB: unused portions of the spritemap ROM contain hex FF's. +It is a useful coding check to warn in the log if these +are being accessed. [They can be inadvertently while +spriteram is being tested, take no notice of that.] + +Heavy use is made of sprite zooming. + + *** + + Sprite table layout (4 long words per entry) + + ------------------------------------------ + 0 | ........ x....... ........ ........ | Flip X + 0 | ........ .xxxxxxx ........ ........ | ZoomX + 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile + | | + 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*] + 2 | ........ ......xx xxxxxx.. ........ | Palette bank + 2 | ........ ........ ......xx xxxxxxxx | X position + | | + 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64) + 3 | ........ ......x. ........ ........ | Flip Y + 3 | ........ .......x xxxxxx.. ........ | ZoomY + 3 | ........ ........ ......xx xxxxxxxx | Y position + ------------------------------------------ + + [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???] + +********************************************************/ + +void gunbustr_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, const u32 *primasks, int x_offs, int y_offs) +{ + int sprites_flipscreen = 0; + + /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list + while processing sprite ram and then draw them all at the end */ + struct gb_tempsprite *sprite_ptr = m_spritelist.get(); + + for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4) + { + u32 data = m_spriteram[offs + 0]; + int flipx = (data & 0x00800000) >> 23; + int zoomx = (data & 0x007f0000) >> 16; + const u32 tilenum = (data & 0x00007fff); + + data = m_spriteram[offs + 2]; + const int priority = (data & 0x000c0000) >> 18; + int color = (data & 0x0003fc00) >> 10; + int x = (data & 0x000003ff); + + data = m_spriteram[offs + 3]; + const int dblsize = (data & 0x00040000) >> 18; + int flipy = (data & 0x00020000) >> 17; + int zoomy = (data & 0x0001fc00) >> 10; + int y = (data & 0x000003ff); + + color |= 0x80; + + if (!tilenum) continue; + + flipy = !flipy; + zoomx += 1; + zoomy += 1; + + y += y_offs; + + // treat coords as signed + if (x > 0x340) x -= 0x400; + if (y > 0x340) y -= 0x400; + + x -= x_offs; + + int bad_chunks = 0; + const int dimension = ((dblsize * 2) + 2); // 2 or 4 + const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16 + const int map_offset = tilenum << 2; + + for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++) + { + const int j = sprite_chunk / dimension; // rows + const int k = sprite_chunk % dimension; // chunks per row + + int px = k; + int py = j; + // pick tiles back to front for x and y flips + if (flipx) px = dimension - 1 - k; + if (flipy) py = dimension - 1 - j; + + const u32 code = m_spritemap[map_offset + px + (py << (dblsize + 1))]; + + if (code == 0xffff) + { + bad_chunks += 1; + continue; + } + + int curx = x + ((k * zoomx) / dimension); + int cury = y + ((j * zoomy) / dimension); + + const int zx = x + (((k + 1) * zoomx) / dimension) - curx; + const int zy = y + (((j + 1) * zoomy) / dimension) - cury; + + if (sprites_flipscreen) + { + /* -zx/y is there to fix zoomed sprite coords in screenflip. + drawgfxzoom does not know to draw from flip-side of sprites when + screen is flipped; so we must correct the coords ourselves. */ + + curx = 320 - curx - zx; + cury = 256 - cury - zy; + flipx = !flipx; + flipy = !flipy; + } + + sprite_ptr->gfx = 0; + sprite_ptr->code = code; + sprite_ptr->color = color; + sprite_ptr->flipx = !flipx; + sprite_ptr->flipy = flipy; + sprite_ptr->x = curx; + sprite_ptr->y = cury; + sprite_ptr->zoomx = zx << 12; + sprite_ptr->zoomy = zy << 12; + + if (primasks) + { + sprite_ptr->primask = primasks[priority]; + + sprite_ptr++; + } + else + { + m_gfxdecode->gfx(sprite_ptr->gfx)->zoom_transpen(bitmap, cliprect, + sprite_ptr->code, + sprite_ptr->color, + sprite_ptr->flipx, sprite_ptr->flipy, + sprite_ptr->x, sprite_ptr->y, + sprite_ptr->zoomx, sprite_ptr->zoomy, 0); + } + } + + if (bad_chunks) + LOGBADSPRITES("Sprite number %04x had %02x invalid chunks\n", tilenum, bad_chunks); + } + + // this happens only if primsks != nullptr + while (sprite_ptr != m_spritelist.get()) + { + sprite_ptr--; + + m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap, cliprect, + sprite_ptr->code, + sprite_ptr->color, + sprite_ptr->flipx, sprite_ptr->flipy, + sprite_ptr->x, sprite_ptr->y, + sprite_ptr->zoomx, sprite_ptr->zoomy, + screen.priority(), sprite_ptr->primask, 0); + } +} + + + +/************************************************************** + SCREEN REFRESH +**************************************************************/ + +u32 gunbustr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + u8 layer[5]; + static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0}; + + m_tc0480scp->tilemap_update(); + + u16 const priority = m_tc0480scp->get_bg_priority(); + layer[0] = (priority & 0xf000) >> 12; // tells us which bg layer is bottom + layer[1] = (priority & 0x0f00) >> 8; + layer[2] = (priority & 0x00f0) >> 4; + layer[3] = (priority & 0x000f) >> 0; // tells us which is top + layer[4] = 4; // text layer always over bg layers + + screen.priority().fill(0, cliprect); + + /* We have to assume 2nd to bottom layer is always underneath + sprites as pdrawgfx cannot yet cope with more than 4 layers */ + +#ifdef MAME_DEBUG + if (!machine().input().code_pressed (KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0); + if (!machine().input().code_pressed (KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1); + if (!machine().input().code_pressed (KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2); + if (!machine().input().code_pressed (KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4); + if (!machine().input().code_pressed (KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8); + if (!machine().input().code_pressed (KEYCODE_N)) draw_sprites(screen, bitmap, cliprect, primasks, 48, -116); +#else + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0); + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1); + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2); + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4); + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8); // text layer + draw_sprites(screen, bitmap, cliprect, primasks, 48, -116); +#endif + return 0; +} + + +// machine + /*********************************************************************/ TIMER_CALLBACK_MEMBER(gunbustr_state::trigger_irq5) @@ -66,7 +388,7 @@ TIMER_CALLBACK_MEMBER(gunbustr_state::trigger_irq5) INTERRUPT_GEN_MEMBER(gunbustr_state::gunbustr_interrupt) { - m_interrupt5_timer->adjust(m_maincpu->cycles_to_attotime(200000-500)); + m_interrupt5_timer->adjust(m_maincpu->cycles_to_attotime(200000 - 500)); device.execute().set_input_line(4, HOLD_LINE); } @@ -87,9 +409,9 @@ void gunbustr_state::motor_control_w(u32 data) { // Standard value poked into MSW is 0x3c00 // (0x2000 and zero are written at startup) - output().set_value("Player1_Gun_Recoil", BIT(data, 24)); - output().set_value("Player2_Gun_Recoil", BIT(data, 16)); - output().set_value("Hit_lamp", BIT(data, 18)); + m_gun_recoil_pl[0] = BIT(data, 24); + m_gun_recoil_pl[1] = BIT(data, 16); + m_hit_lamp = BIT(data, 18); } @@ -102,7 +424,7 @@ u32 gunbustr_state::gun_r() void gunbustr_state::gun_w(u32 data) { - /* 10000 cycle delay is arbitrary */ + // 10000 cycle delay is arbitrary m_interrupt5_timer->adjust(m_maincpu->cycles_to_attotime(10000)); } @@ -111,19 +433,19 @@ void gunbustr_state::gun_w(u32 data) MEMORY STRUCTURES ***********************************************************/ -void gunbustr_state::gunbustr_map(address_map &map) +void gunbustr_state::prg_map(address_map &map) { map(0x000000, 0x0fffff).rom(); - map(0x200000, 0x21ffff).ram().share("ram"); /* main CPUA ram */ - map(0x300000, 0x301fff).ram().share("spriteram"); /* Sprite ram */ - map(0x380000, 0x380003).w(FUNC(gunbustr_state::motor_control_w)); /* motor, lamps etc. */ - map(0x390000, 0x3907ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); /* Sound shared ram */ + map(0x200000, 0x21ffff).ram().share(m_ram); // main CPUA RAM + map(0x300000, 0x301fff).ram().share(m_spriteram); + map(0x380000, 0x380003).w(FUNC(gunbustr_state::motor_control_w)); // motor, lamps etc. + map(0x390000, 0x3907ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w)); // Sound shared RAM map(0x400000, 0x400007).rw("tc0510nio", FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write)); - map(0x500000, 0x500003).rw(FUNC(gunbustr_state::gun_r), FUNC(gunbustr_state::gun_w)); /* gun coord read */ + map(0x500000, 0x500003).rw(FUNC(gunbustr_state::gun_r), FUNC(gunbustr_state::gun_w)); map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); map(0x830000, 0x83002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w)); map(0x900000, 0x901fff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); - map(0xc00000, 0xc03fff).ram(); /* network ram ?? */ + map(0xc00000, 0xc03fff).ram(); // network RAM ? } /*********************************************************** @@ -132,7 +454,7 @@ void gunbustr_state::gunbustr_map(address_map &map) static INPUT_PORTS_START( gunbustr ) PORT_START("SPECIAL") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) /* Freeze input */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) // Freeze input PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -171,7 +493,7 @@ static INPUT_PORTS_START( gunbustr ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - /* Light gun inputs */ + // Light gun inputs PORT_START("LIGHT0_X") PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(1) @@ -193,13 +515,13 @@ INPUT_PORTS_END static const gfx_layout tile16x16_layout = { - 16,16, /* 16*16 sprites */ + 16,16, // 16*16 sprites RGN_FRAC(1,1), - 4, /* 4 bits per pixel */ + 4, // 4 bits per pixel { STEP4(0,16) }, { STEP16(0,1) }, { STEP16(0,16*4) }, - 16*16*4 /* every sprite takes 128 consecutive bytes */ + 16*16*4 // every sprite takes 128 consecutive bytes }; static GFXDECODE_START( gfx_gunbustr ) @@ -213,10 +535,10 @@ GFXDECODE_END void gunbustr_state::gunbustr(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware M68EC020(config, m_maincpu, XTAL(16'000'000)); - m_maincpu->set_addrmap(AS_PROGRAM, &gunbustr_state::gunbustr_map); - m_maincpu->set_vblank_int("screen", FUNC(gunbustr_state::gunbustr_interrupt)); /* VBL */ + m_maincpu->set_addrmap(AS_PROGRAM, &gunbustr_state::prg_map); + m_maincpu->set_vblank_int("screen", FUNC(gunbustr_state::gunbustr_interrupt)); // VBL EEPROM_93C46_16BIT(config, "eeprom"); @@ -230,7 +552,7 @@ void gunbustr_state::gunbustr(machine_config &config) tc0510nio.write_4_callback().set(FUNC(gunbustr_state::coin_word_w)); tc0510nio.read_7_callback().set_ioport("SYSTEM"); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); @@ -248,7 +570,7 @@ void gunbustr_state::gunbustr(machine_config &config) m_tc0480scp->set_offsets_tx(-1, -1); m_tc0480scp->set_offsets_flip(-1, 0); - /* sound hardware */ + // sound hardware SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -260,28 +582,28 @@ void gunbustr_state::gunbustr(machine_config &config) /***************************************************************************/ ROM_START( gunbustr ) - ROM_REGION( 0x100000, "maincpu", 0 ) /* 1024K for 68020 code (CPU A) */ + ROM_REGION( 0x100000, "maincpu", 0 ) // 68020 code (CPU A) ROM_LOAD32_BYTE( "d27-23.bin", 0x00000, 0x40000, CRC(cd1037cc) SHA1(8005a6a84081ce609e7a605ec8e00e740bfc6846) ) ROM_LOAD32_BYTE( "d27-22.bin", 0x00001, 0x40000, CRC(475949fc) SHA1(3d5aa3411d2618004902f9d05dff61d9af01ff35) ) ROM_LOAD32_BYTE( "d27-21.bin", 0x00002, 0x40000, CRC(60950a8a) SHA1(a0336bf6970baa6eaa998a112db840a7fd0452d7) ) ROM_LOAD32_BYTE( "d27-27.bin", 0x00003, 0x40000, CRC(fd7d3d4c) SHA1(df42e135b1e9b7e371971ba7c8a2e161f3623aa3) ) - ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) /* Sound cpu */ + ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) ROM_LOAD16_BYTE( "d27-25.bin", 0x100000, 0x20000, CRC(c88203cf) SHA1(a918d395b471acdce56dacabd7a1e1e023948365) ) ROM_LOAD16_BYTE( "d27-24.bin", 0x100001, 0x20000, CRC(084bd8bd) SHA1(93229bc7de4550ead1bb12f666ddbacbe357488d) ) - ROM_REGION( 0x100000, "tc0480scp", 0 ) - ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) /* SCR 16x16 tiles */ + ROM_REGION( 0x100000, "tc0480scp", 0 ) // SCR 16x16 tiles + ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) ROM_LOAD32_WORD( "d27-02.bin", 0x00002, 0x80000, CRC(92ab6430) SHA1(28ed80391c732b09d10c74ed6b78ac76cb62e083) ) - ROM_REGION( 0x400000, "sprites", 0 ) - ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) /* OBJ 16x16 tiles: each rom has 1 bitplane */ + ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles: each ROM has 1 bitplane + ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) ROM_LOAD64_WORD_SWAP( "d27-05.bin", 0x000004, 0x100000, CRC(96d7c1a5) SHA1(93b6a7aea397280a5a778e736d433a85cb7da52c) ) ROM_LOAD64_WORD_SWAP( "d27-06.bin", 0x000002, 0x100000, CRC(bbb934db) SHA1(9e9b5cf05b9275f1182f5b499b8ee897c4f25b96) ) ROM_LOAD64_WORD_SWAP( "d27-07.bin", 0x000000, 0x100000, CRC(8ab4854e) SHA1(bd2750cdaa2918e56f8aef3732875952a1eeafea) ) - ROM_REGION16_LE( 0x80000, "spritemap", 0 ) - ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) /* STY, used to create big sprites on the fly */ + ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY, used to create big sprites on the fly + ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) ROM_REGION16_BE( 0x800000, "taito_en:ensoniq" , ROMREGION_ERASE00 ) ROM_LOAD16_BYTE( "d27-08.bin", 0x000000, 0x100000, CRC(7c147e30) SHA1(b605045154967050ec06391798da4afe3686a6e1) ) // C8, C9 @@ -294,28 +616,28 @@ ROM_START( gunbustr ) ROM_END ROM_START( gunbustru ) - ROM_REGION( 0x100000, "maincpu", 0 ) /* 1024K for 68020 code (CPU A) */ + ROM_REGION( 0x100000, "maincpu", 0 ) // 68020 code (CPU A) ROM_LOAD32_BYTE( "d27-23.bin", 0x00000, 0x40000, CRC(cd1037cc) SHA1(8005a6a84081ce609e7a605ec8e00e740bfc6846) ) ROM_LOAD32_BYTE( "d27-22.bin", 0x00001, 0x40000, CRC(475949fc) SHA1(3d5aa3411d2618004902f9d05dff61d9af01ff35) ) ROM_LOAD32_BYTE( "d27-21.bin", 0x00002, 0x40000, CRC(60950a8a) SHA1(a0336bf6970baa6eaa998a112db840a7fd0452d7) ) ROM_LOAD32_BYTE( "d27-26.bin", 0x00003, 0x40000, CRC(8a7a0dda) SHA1(59ee7c391c170ab05a3d3d940d833c65e265d9b3) ) - ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) /* Sound cpu */ + ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) ROM_LOAD16_BYTE( "d27-25.bin", 0x100000, 0x20000, CRC(c88203cf) SHA1(a918d395b471acdce56dacabd7a1e1e023948365) ) ROM_LOAD16_BYTE( "d27-24.bin", 0x100001, 0x20000, CRC(084bd8bd) SHA1(93229bc7de4550ead1bb12f666ddbacbe357488d) ) - ROM_REGION( 0x100000, "tc0480scp", 0 ) - ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) /* SCR 16x16 tiles */ + ROM_REGION( 0x100000, "tc0480scp", 0 ) // SCR 16x16 tiles + ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) ROM_LOAD32_WORD( "d27-02.bin", 0x00002, 0x80000, CRC(92ab6430) SHA1(28ed80391c732b09d10c74ed6b78ac76cb62e083) ) - ROM_REGION( 0x400000, "sprites", 0 ) - ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) /* OBJ 16x16 tiles: each rom has 1 bitplane */ + ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles: each ROM has 1 bitplane + ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) ROM_LOAD64_WORD_SWAP( "d27-05.bin", 0x000004, 0x100000, CRC(96d7c1a5) SHA1(93b6a7aea397280a5a778e736d433a85cb7da52c) ) ROM_LOAD64_WORD_SWAP( "d27-06.bin", 0x000002, 0x100000, CRC(bbb934db) SHA1(9e9b5cf05b9275f1182f5b499b8ee897c4f25b96) ) ROM_LOAD64_WORD_SWAP( "d27-07.bin", 0x000000, 0x100000, CRC(8ab4854e) SHA1(bd2750cdaa2918e56f8aef3732875952a1eeafea) ) - ROM_REGION16_LE( 0x80000, "spritemap", 0 ) - ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) /* STY, used to create big sprites on the fly */ + ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY, used to create big sprites on the fly + ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) ROM_REGION16_BE( 0x800000, "taito_en:ensoniq" , ROMREGION_ERASE00 ) ROM_LOAD16_BYTE( "d27-08.bin", 0x000000, 0x100000, CRC(7c147e30) SHA1(b605045154967050ec06391798da4afe3686a6e1) ) // C8, C9 @@ -328,28 +650,28 @@ ROM_START( gunbustru ) ROM_END ROM_START( gunbustrj ) - ROM_REGION( 0x100000, "maincpu", 0 ) /* 1024K for 68020 code (CPU A) */ + ROM_REGION( 0x100000, "maincpu", 0 ) // 68020 code (CPU A) ROM_LOAD32_BYTE( "d27-23.bin", 0x00000, 0x40000, CRC(cd1037cc) SHA1(8005a6a84081ce609e7a605ec8e00e740bfc6846) ) ROM_LOAD32_BYTE( "d27-22.bin", 0x00001, 0x40000, CRC(475949fc) SHA1(3d5aa3411d2618004902f9d05dff61d9af01ff35) ) ROM_LOAD32_BYTE( "d27-21.bin", 0x00002, 0x40000, CRC(60950a8a) SHA1(a0336bf6970baa6eaa998a112db840a7fd0452d7) ) ROM_LOAD32_BYTE( "d27-20.bin", 0x00003, 0x40000, CRC(13735c60) SHA1(65b762b28d51b295f6fe190420af566b1b3d4a82) ) - ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) /* Sound cpu */ + ROM_REGION( 0x140000, "taito_en:audiocpu", 0 ) ROM_LOAD16_BYTE( "d27-25.bin", 0x100000, 0x20000, CRC(c88203cf) SHA1(a918d395b471acdce56dacabd7a1e1e023948365) ) ROM_LOAD16_BYTE( "d27-24.bin", 0x100001, 0x20000, CRC(084bd8bd) SHA1(93229bc7de4550ead1bb12f666ddbacbe357488d) ) - ROM_REGION( 0x100000, "tc0480scp", 0 ) - ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) /* SCR 16x16 tiles */ + ROM_REGION( 0x100000, "tc0480scp", 0 ) // SCR 16x16 tiles + ROM_LOAD32_WORD( "d27-01.bin", 0x00000, 0x80000, CRC(f41759ce) SHA1(30789f43dd09b56399e1dfdb8c6a1e01a21562bd) ) ROM_LOAD32_WORD( "d27-02.bin", 0x00002, 0x80000, CRC(92ab6430) SHA1(28ed80391c732b09d10c74ed6b78ac76cb62e083) ) - ROM_REGION( 0x400000, "sprites", 0 ) - ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) /* OBJ 16x16 tiles: each rom has 1 bitplane */ + ROM_REGION( 0x400000, "sprites", 0 ) // OBJ 16x16 tiles: each ROM has 1 bitplane + ROM_LOAD64_WORD_SWAP( "d27-04.bin", 0x000006, 0x100000, CRC(ff8b9234) SHA1(6095b7daf9b7e9a22b0d44d9d6a642ddecb2bd29) ) ROM_LOAD64_WORD_SWAP( "d27-05.bin", 0x000004, 0x100000, CRC(96d7c1a5) SHA1(93b6a7aea397280a5a778e736d433a85cb7da52c) ) ROM_LOAD64_WORD_SWAP( "d27-06.bin", 0x000002, 0x100000, CRC(bbb934db) SHA1(9e9b5cf05b9275f1182f5b499b8ee897c4f25b96) ) ROM_LOAD64_WORD_SWAP( "d27-07.bin", 0x000000, 0x100000, CRC(8ab4854e) SHA1(bd2750cdaa2918e56f8aef3732875952a1eeafea) ) - ROM_REGION16_LE( 0x80000, "spritemap", 0 ) - ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) /* STY, used to create big sprites on the fly */ + ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY, used to create big sprites on the fly + ROM_LOAD16_WORD( "d27-03.bin", 0x00000, 0x80000, CRC(23bf2000) SHA1(49b29e771a47fcd7e6cd4e2704b217f9727f8299) ) ROM_REGION16_BE( 0x800000, "taito_en:ensoniq" , ROMREGION_ERASE00 ) ROM_LOAD16_BYTE( "d27-08.bin", 0x000000, 0x100000, CRC(7c147e30) SHA1(b605045154967050ec06391798da4afe3686a6e1) ) // C8, C9 @@ -363,7 +685,7 @@ ROM_END u32 gunbustr_state::main_cycle_r() { - if (m_maincpu->pc() == 0x55a && (m_ram[0x3acc/4] & 0xff000000) == 0) + if (m_maincpu->pc() == 0x55a && (m_ram[0x3acc / 4] & 0xff000000) == 0) m_maincpu->spin_until_interrupt(); return m_ram[0x3acc/4]; @@ -371,7 +693,7 @@ u32 gunbustr_state::main_cycle_r() void gunbustr_state::init_gunbustr() { - /* Speedup handler */ + // Speedup handler m_maincpu->space(AS_PROGRAM).install_read_handler(0x203acc, 0x203acf, read32smo_delegate(*this, FUNC(gunbustr_state::main_cycle_r))); m_interrupt5_timer = timer_alloc(FUNC(gunbustr_state::trigger_irq5), this); @@ -385,6 +707,9 @@ void gunbustr_state::init_gunbustrj() m_coin_lockout = false; } -GAME( 1992, gunbustr, 0, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito Corporation Japan", "Gunbuster (World)", MACHINE_NODEVICE_LAN ) -GAME( 1992, gunbustru, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito America Corporation", "Gunbuster (US)", MACHINE_NODEVICE_LAN ) -GAME( 1992, gunbustrj, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustrj,ORIENTATION_FLIP_X, "Taito Corporation", "Gunbuster (Japan)", MACHINE_NODEVICE_LAN ) +} // anonymous namespace + + +GAME( 1992, gunbustr, 0, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito Corporation Japan", "Gunbuster (World)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, gunbustru, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustr, ORIENTATION_FLIP_X, "Taito America Corporation", "Gunbuster (US)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, gunbustrj, gunbustr, gunbustr, gunbustr, gunbustr_state, init_gunbustrj,ORIENTATION_FLIP_X, "Taito Corporation", "Gunbuster (Japan)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/taito/gunbustr.h b/src/mame/taito/gunbustr.h deleted file mode 100644 index 21d33e9b788..00000000000 --- a/src/mame/taito/gunbustr.h +++ /dev/null @@ -1,79 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Bryan McPhail, David Graves -#ifndef MAME_INCLUDES_GUNBUSTR_H -#define MAME_INCLUDES_GUNBUSTR_H - -#pragma once - -#include "machine/eepromser.h" -#include "tc0480scp.h" -#include "emupal.h" - -struct gb_tempsprite -{ - int gfx = 0; - int code = 0, color = 0; - int flipx,flipy = 0; - int x = 0, y = 0; - int zoomx = 0, zoomy = 0; - int primask = 0; -}; - -class gunbustr_state : public driver_device -{ -public: - gunbustr_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this,"maincpu"), - m_tc0480scp(*this, "tc0480scp"), - m_ram(*this,"ram"), - m_spriteram(*this,"spriteram"), - m_eeprom(*this, "eeprom"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_spritemap(*this, "spritemap"), - m_io_light_x(*this, "LIGHT%u_X", 0U), - m_io_light_y(*this, "LIGHT%u_Y", 0U) - { - m_coin_lockout = true; - } - - void gunbustr(machine_config &config); - - void init_gunbustrj(); - void init_gunbustr(); - -private: - virtual void video_start() override; - - void gunbustr_map(address_map &map); - - TIMER_CALLBACK_MEMBER(trigger_irq5); - - void motor_control_w(u32 data); - u32 gun_r(); - void gun_w(u32 data); - u32 main_cycle_r(); - void coin_word_w(u8 data); - u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(gunbustr_interrupt); - void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs); - - required_device m_maincpu; - required_device m_tc0480scp; - required_shared_ptr m_ram; - required_shared_ptr m_spriteram; - required_device m_eeprom; - required_device m_gfxdecode; - required_device m_palette; - required_region_ptr m_spritemap; - - required_ioport_array<2> m_io_light_x; - required_ioport_array<2> m_io_light_y; - - bool m_coin_lockout; - std::unique_ptr m_spritelist{}; - emu_timer *m_interrupt5_timer = nullptr; -}; - -#endif // MAME_INCLUDES_GUNBUSTR_H diff --git a/src/mame/taito/gunbustr_v.cpp b/src/mame/taito/gunbustr_v.cpp deleted file mode 100644 index b9520f11daa..00000000000 --- a/src/mame/taito/gunbustr_v.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Bryan McPhail, David Graves -#include "emu.h" -#include "gunbustr.h" -#include "screen.h" - -/************************************************************/ - -void gunbustr_state::video_start() -{ - m_spritelist = std::make_unique(0x4000); -} - -/************************************************************ - SPRITE DRAW ROUTINES - -We draw a series of small tiles ("chunks") together to -create each big sprite. The spritemap rom provides the lookup -table for this. The game hardware looks up 16x16 sprite chunks -from the spritemap rom, creating a 64x64 sprite like this: - - 0 1 2 3 - 4 5 6 7 - 8 9 10 11 - 12 13 14 15 - -(where the number is the word offset into the spritemap rom). -It can also create 32x32 sprites. - -NB: unused portions of the spritemap rom contain hex FF's. -It is a useful coding check to warn in the log if these -are being accessed. [They can be inadvertently while -spriteram is being tested, take no notice of that.] - -Heavy use is made of sprite zooming. - - *** - - Sprite table layout (4 long words per entry) - - ------------------------------------------ - 0 | ........ x....... ........ ........ | Flip X - 0 | ........ .xxxxxxx ........ ........ | ZoomX - 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile - | | - 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*] - 2 | ........ ......xx xxxxxx.. ........ | Palette bank - 2 | ........ ........ ......xx xxxxxxxx | X position - | | - 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64) - 3 | ........ ......x. ........ ........ | Flip Y - 3 | ........ .......x xxxxxx.. ........ | ZoomY - 3 | ........ ........ ......xx xxxxxxxx | Y position - ------------------------------------------ - - [* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???] - -********************************************************/ - -void gunbustr_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs) -{ - int sprites_flipscreen = 0; - - /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list - while processing sprite ram and then draw them all at the end */ - struct gb_tempsprite *sprite_ptr = m_spritelist.get(); - - for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4) - { - u32 data = m_spriteram[offs+0]; - int flipx = (data & 0x00800000) >> 23; - int zoomx = (data & 0x007f0000) >> 16; - const u32 tilenum = (data & 0x00007fff); - - data = m_spriteram[offs+2]; - const int priority = (data & 0x000c0000) >> 18; - int color = (data & 0x0003fc00) >> 10; - int x = (data & 0x000003ff); - - data = m_spriteram[offs+3]; - const int dblsize = (data & 0x00040000) >> 18; - int flipy = (data & 0x00020000) >> 17; - int zoomy = (data & 0x0001fc00) >> 10; - int y = (data & 0x000003ff); - - color |= 0x80; - - if (!tilenum) continue; - - flipy = !flipy; - zoomx += 1; - zoomy += 1; - - y += y_offs; - - /* treat coords as signed */ - if (x > 0x340) x -= 0x400; - if (y > 0x340) y -= 0x400; - - x -= x_offs; - - int bad_chunks = 0; - const int dimension = ((dblsize*2) + 2); // 2 or 4 - const int total_chunks = ((dblsize*3) + 1) << 2; // 4 or 16 - const int map_offset = tilenum << 2; - - for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++) - { - const int j = sprite_chunk / dimension; /* rows */ - const int k = sprite_chunk % dimension; /* chunks per row */ - - int px = k; - int py = j; - /* pick tiles back to front for x and y flips */ - if (flipx) px = dimension - 1 - k; - if (flipy) py = dimension - 1 - j; - - const u32 code = m_spritemap[map_offset + px + (py<<(dblsize+1))]; - - if (code == 0xffff) - { - bad_chunks += 1; - continue; - } - - int curx = x + ((k * zoomx) / dimension); - int cury = y + ((j * zoomy) / dimension); - - const int zx = x + (((k + 1) * zoomx) / dimension) - curx; - const int zy = y + (((j + 1) * zoomy) / dimension) - cury; - - if (sprites_flipscreen) - { - /* -zx/y is there to fix zoomed sprite coords in screenflip. - drawgfxzoom does not know to draw from flip-side of sprites when - screen is flipped; so we must correct the coords ourselves. */ - - curx = 320 - curx - zx; - cury = 256 - cury - zy; - flipx = !flipx; - flipy = !flipy; - } - - sprite_ptr->gfx = 0; - sprite_ptr->code = code; - sprite_ptr->color = color; - sprite_ptr->flipx = !flipx; - sprite_ptr->flipy = flipy; - sprite_ptr->x = curx; - sprite_ptr->y = cury; - sprite_ptr->zoomx = zx << 12; - sprite_ptr->zoomy = zy << 12; - - if (primasks) - { - sprite_ptr->primask = primasks[priority]; - - sprite_ptr++; - } - else - { - m_gfxdecode->gfx(sprite_ptr->gfx)->zoom_transpen(bitmap,cliprect, - sprite_ptr->code, - sprite_ptr->color, - sprite_ptr->flipx,sprite_ptr->flipy, - sprite_ptr->x,sprite_ptr->y, - sprite_ptr->zoomx,sprite_ptr->zoomy,0); - } - } - - if (bad_chunks) -logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks); - } - - /* this happens only if primsks != nullptr */ - while (sprite_ptr != m_spritelist.get()) - { - sprite_ptr--; - - m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap,cliprect, - sprite_ptr->code, - sprite_ptr->color, - sprite_ptr->flipx,sprite_ptr->flipy, - sprite_ptr->x,sprite_ptr->y, - sprite_ptr->zoomx,sprite_ptr->zoomy, - screen.priority(),sprite_ptr->primask,0); - } -} - - - -/************************************************************** - SCREEN REFRESH -**************************************************************/ - -u32 gunbustr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - u8 layer[5]; - u16 priority; - static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0}; - - m_tc0480scp->tilemap_update(); - - priority = m_tc0480scp->get_bg_priority(); - layer[0] = (priority & 0xf000) >> 12; /* tells us which bg layer is bottom */ - layer[1] = (priority & 0x0f00) >> 8; - layer[2] = (priority & 0x00f0) >> 4; - layer[3] = (priority & 0x000f) >> 0; /* tells us which is top */ - layer[4] = 4; /* text layer always over bg layers */ - - screen.priority().fill(0, cliprect); - - /* We have to assume 2nd to bottom layer is always underneath - sprites as pdrawgfx cannot yet cope with more than 4 layers */ - -#ifdef MAME_DEBUG - if (!machine().input().code_pressed (KEYCODE_Z)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0],TILEMAP_DRAW_OPAQUE, 0); - if (!machine().input().code_pressed (KEYCODE_X)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1); - if (!machine().input().code_pressed (KEYCODE_C)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2); - if (!machine().input().code_pressed (KEYCODE_V)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4); - if (!machine().input().code_pressed (KEYCODE_B)) m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8); - if (!machine().input().code_pressed (KEYCODE_N)) draw_sprites(screen, bitmap, cliprect, primasks, 48, -116); -#else - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0); - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1); - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 2); - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 4); - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 8); /* text layer */ - draw_sprites(screen, bitmap, cliprect, primasks, 48, -116); -#endif - return 0; -} diff --git a/src/mame/taito/msisaac.cpp b/src/mame/taito/msisaac.cpp index 1a46a5fa95b..f9e789b5bf3 100644 --- a/src/mame/taito/msisaac.cpp +++ b/src/mame/taito/msisaac.cpp @@ -1,5 +1,6 @@ // license:GPL-2.0+ -// copyright-holders:Jarek Burczynski +// copyright-holders: Jarek Burczynski + /**************************************************************************** Metal Soldier Isaac II (c) Taito 1985 @@ -15,14 +16,347 @@ ****************************************************************************/ #include "emu.h" -#include "msisaac.h" + +#include "taito68705.h" #include "cpu/z80/z80.h" #include "cpu/m6805/m6805.h" +#include "machine/gen_latch.h" #include "sound/ay8910.h" +#include "sound/msm5232.h" +#include "sound/ta7630.h" + +#include "emupal.h" #include "screen.h" #include "speaker.h" +#include "tilemap.h" + + +// configurable logging +#define LOG_BG2CTRL (1U << 1) +#define LOG_UNKWRITE (1U << 2) +#define LOG_MCU (1U << 3) +#define LOG_SOUND (1U << 4) + +//#define VERBOSE (LOG_GENERAL | LOG_BG2CTRL | LOG_UNKWRITE | LOGMCU | LOGSOUND) + +#include "logmacro.h" + +#define LOGBG2CTRL(...) LOGMASKED(LOG_BG2CTRL, __VA_ARGS__) +#define LOGUNKWRITE(...) LOGMASKED(LOG_UNKWRITE, __VA_ARGS__) +#define LOGMCU(...) LOGMASKED(LOG_MCU, __VA_ARGS__) +#define LOGSOUND(...) LOGMASKED(LOG_SOUND, __VA_ARGS__) + + +namespace { + +// Disabled because the MCU dump is currently unavailable. -AS +//#define USE_MCU + +class msisaac_state : public driver_device +{ +public: + msisaac_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_spriteram(*this, "spriteram"), + m_videoram(*this, "videoram%u", 1U), + m_audiocpu(*this, "audiocpu"), + m_maincpu(*this, "maincpu"), + m_bmcu(*this, "bmcu"), + m_msm(*this, "msm"), + m_ta7630(*this, "ta7630"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette"), + m_soundlatch(*this, "soundlatch"), + m_in1(*this, "IN1") + { } + + void msisaac(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: + // memory pointers + required_shared_ptr m_spriteram; + required_shared_ptr_array m_videoram; + + // video-related + bitmap_ind16 *m_tmp_bitmap[2]{}; + tilemap_t *m_bg_tilemap[2]{}; + tilemap_t *m_fg_tilemap = nullptr; + uint8_t m_bg2_textbank = 0; + + // sound-related + uint8_t m_sound_nmi_enable = 0; + uint8_t m_pending_nmi = 0; + + // fake MCU +#ifndef USE_MCU + uint8_t m_mcu_val = 0; + uint8_t m_direction = 0; +#endif + + uint8_t m_snd_ctrl[2]{}; + + // devices + required_device m_audiocpu; + required_device m_maincpu; + optional_device m_bmcu; + required_device m_msm; + required_device m_ta7630; + required_device m_gfxdecode; + required_device m_palette; + required_device m_soundlatch; + + required_ioport m_in1; + + void sound_command_w(uint8_t data); + void nmi_disable_w(uint8_t data); + void nmi_enable_w(uint8_t data); + void unknown_w(uint8_t data); + uint8_t mcu_r(offs_t offset); + uint8_t mcu_status_r(offs_t offset); + void mcu_w(offs_t offset, uint8_t data); + void fg_scrolly_w(uint8_t data); + void fg_scrollx_w(uint8_t data); + void bg2_scrollx_w(uint8_t data); + template void bg_scrolly_w(uint8_t data); + void bg_scrollx_w(uint8_t data); + void bg2_textbank_w(uint8_t data); + template void bg_videoram_w(offs_t offset, uint8_t data); + void fg_videoram_w(offs_t offset, uint8_t data); + void sound_control_0_w(uint8_t data); + void sound_control_1_w(uint8_t data); + TILE_GET_INFO_MEMBER(get_fg_tile_info); + TILE_GET_INFO_MEMBER(get_bg_tile_info); + TILE_GET_INFO_MEMBER(get_bg2_tile_info); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_CALLBACK_MEMBER(nmi_callback); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + void main_map(address_map &map); + void sound_map(address_map &map); +}; + + +// video + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +TILE_GET_INFO_MEMBER(msisaac_state::get_fg_tile_info) +{ + int const tile_number = m_videoram[0][tile_index]; + tileinfo.set(0, + tile_number, + 0x10, + 0); +} + +TILE_GET_INFO_MEMBER(msisaac_state::get_bg_tile_info) +{ + int const tile_number = m_videoram[1][tile_index]; + tileinfo.set(1, + 0x100 + tile_number, + 0x30, + 0); +} + +TILE_GET_INFO_MEMBER(msisaac_state::get_bg2_tile_info) +{ + int const tile_number = m_videoram[2][tile_index]; + + // graphics 0 or 1 + int const gfx_b = (m_bg2_textbank >> 3) & 1; + + tileinfo.set(gfx_b, + tile_number, + 0x20, + 0); +} + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +void msisaac_state::video_start() +{ + m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + + m_bg_tilemap[1]->set_transparent_pen(0); + m_fg_tilemap->set_transparent_pen(0); +} + + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +void msisaac_state::fg_scrolly_w(uint8_t data) +{ + m_fg_tilemap->set_scrolly(0, data); +} + +void msisaac_state::fg_scrollx_w(uint8_t data) +{ + m_fg_tilemap->set_scrollx(0, 9 + data); +} +template +void msisaac_state::bg_scrolly_w(uint8_t data) +{ + m_bg_tilemap[Which]->set_scrolly(0, data); +} + +void msisaac_state::bg_scrollx_w(uint8_t data) +{ + m_bg_tilemap[0]->set_scrollx(0, 9 + 2 + data); +} + +void msisaac_state::bg2_scrollx_w(uint8_t data) +{ + m_bg_tilemap[1]->set_scrollx(0, 9 + 4 + data); +} + + +void msisaac_state::bg2_textbank_w(uint8_t data) +{ + if (m_bg2_textbank != data) + { + m_bg2_textbank = data; + m_bg_tilemap[1]->mark_all_dirty(); + + //check if we are correct on this one + if ((data != 8) && (data != 0)) + { + LOGBG2CTRL("bg2 control = %2x\n", data); + } + } +} + +template +void msisaac_state::bg_videoram_w(offs_t offset, uint8_t data) +{ + m_videoram[Which + 1][offset] = data; + m_bg_tilemap[Which]->mark_tile_dirty(offset); +} + +void msisaac_state::fg_videoram_w(offs_t offset, uint8_t data) +{ + m_videoram[0][offset] = data; + m_fg_tilemap->mark_tile_dirty(offset); +} + + +/*************************************************************************** + + Display refresh + +***************************************************************************/ +void msisaac_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + const uint8_t *source = m_spriteram + 32 * 4 - 4; + const uint8_t *finish = m_spriteram; // ? + + while (source >= finish) + { + int const sx = source[0]; + int const sy = 240 - source[1] - 1; + int const attributes = source[2]; + int const sprite_number = source[3]; + + int const color = (attributes >> 4) & 0xf; + int const flipx = (attributes & 0x1); + int const flipy = (attributes & 0x2); + + gfx_element *gfx = m_gfxdecode->gfx(2); + + if (attributes & 4) + { + //color = machine().rand() & 15; + gfx = m_gfxdecode->gfx(3); + } + + if (attributes & 8) // double size sprite + { + switch (attributes & 3) + { + case 0: // flipx == 0 && flipy == 0 + gfx->transpen(bitmap, cliprect, + sprite_number + 1, color, + flipx, flipy, + sx, sy - 16, 0); + gfx->transpen(bitmap, cliprect, + sprite_number, color, + flipx, flipy, + sx, sy, 0); + break; + case 1: // flipx == 1 && flipy == 0 + gfx->transpen(bitmap, cliprect, + sprite_number + 1, color, + flipx, flipy, + sx, sy - 16, 0); + gfx->transpen(bitmap, cliprect, + sprite_number, color, + flipx, flipy, + sx, sy, 0); + break; + case 2: // flipx == 0 && flipy == 1 + gfx->transpen(bitmap, cliprect, + sprite_number, color, + flipx, flipy, + sx, sy - 16, 0); + gfx->transpen(bitmap, cliprect, + sprite_number + 1, color, + flipx, flipy, + sx, sy, 0); + break; + case 3: // flipx == 1 && flipy == 1 + gfx->transpen(bitmap, cliprect, + sprite_number, color, + flipx, flipy, + sx, sy - 16, 0); + gfx->transpen(bitmap, cliprect, + sprite_number + 1, color, + flipx, flipy, + sx, sy, 0); + break; + } + } + else + { + gfx->transpen(bitmap, cliprect, + sprite_number, + color, + flipx, flipy, + sx, sy, 0); + } + source -= 4; + } +} + +uint32_t msisaac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0); + m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); + draw_sprites(bitmap, cliprect); + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + + +// machine TIMER_CALLBACK_MEMBER(msisaac_state::nmi_callback) { @@ -59,16 +393,16 @@ void msisaac_state::flip_screen_w(uint8_t data) flip_screen_set(data); } -void msisaac_state::msisaac_coin_counter_w(offs_t offset, uint8_t data) +void msisaac_state::coin_counter_w(offs_t offset, uint8_t data) { machine().bookkeeping().coin_counter_w(offset,data); } #endif -void msisaac_state::ms_unknown_w(uint8_t data) +void msisaac_state::unknown_w(uint8_t data) { if (data != 0x08) - popmessage("CPU #0 write to 0xf0a3 data=%2x", data); + LOGUNKWRITE("CPU #0 write to 0xf0a3 data = %2x", data); } @@ -80,7 +414,7 @@ void msisaac_state::ms_unknown_w(uint8_t data) -uint8_t msisaac_state::msisaac_mcu_r(offs_t offset) +uint8_t msisaac_state::mcu_r(offs_t offset) { #ifdef USE_MCU return m_bmcu->buggychl_mcu_r(offset); @@ -88,23 +422,23 @@ uint8_t msisaac_state::msisaac_mcu_r(offs_t offset) /* MCU simulation TODO: \-Find the command which allows player-2 to play. -\-Fix some graphics imperfections(*not* confirmed if they are caused by unhandled +\-Fix some graphics imperfections (*not* confirmed if they are caused by unhandled commands or imperfect video emulation). */ switch (m_mcu_val) { - /*Start-up check*/ + // Start-up check case 0x5f: return (m_mcu_val + 0x6b); - /*These interferes with RAM operations(setting them to non-zero you * - * will have unexpected results,such as infinite lives or score not * + /*These interfere with RAM operations (setting them to non-zero you * + * will have unexpected results, such as infinite lives or score not * * incremented properly).*/ case 0x40: case 0x41: case 0x42: return 0; - /*With this command the MCU controls body direction */ + // With this command the MCU controls body direction case 0x02: { //direction: @@ -117,7 +451,7 @@ MCU simulation TODO: //6-down //7-leftdwn - uint8_t val= (ioport("IN1")->read() >> 2) & 0x0f; + uint8_t val = (m_in1->read() >> 2) & 0x0f; /* bit0 = left bit1 = right bit2 = down @@ -141,60 +475,60 @@ MCU simulation TODO: return m_direction; } - /*This controls the arms when they return to the player. */ + //This controls the arms when they return to the player. case 0x07: return 0x45; default: - logerror("CPU#0 read from MCU pc=%4x, mcu_val=%2x\n", m_maincpu->pc(), m_mcu_val); + LOGMCU("CPU#0 read from MCU pc = %4x, mcu_val = %2x\n", m_maincpu->pc(), m_mcu_val); return m_mcu_val; } #endif } -uint8_t msisaac_state::msisaac_mcu_status_r(offs_t offset) +uint8_t msisaac_state::mcu_status_r(offs_t offset) { #ifdef USE_MCU return m_bmcu->buggychl_mcu_status_r(offset); #else - return 3; //mcu ready / cpu data ready + return 3; // MCU ready / CPU data ready #endif } -void msisaac_state::msisaac_mcu_w(offs_t offset, uint8_t data) +void msisaac_state::mcu_w(offs_t offset, uint8_t data) { #ifdef USE_MCU m_bmcu->buggychl_mcu_w(offset,data); #else - //if(data != 0x0a && data != 0x42 && data != 0x02) - // popmessage("PC = %04x %02x", m_maincpu->pc(), data); + if(data != 0x0a && data != 0x42 && data != 0x02) + LOGMCU("PC = %04x %02x", m_maincpu->pc(), data); m_mcu_val = data; #endif } -void msisaac_state::msisaac_map(address_map &map) +void msisaac_state::main_map(address_map &map) { map(0x0000, 0xdfff).rom(); map(0xe000, 0xe7ff).ram(); map(0xe800, 0xefff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); - map(0xf000, 0xf000).w(FUNC(msisaac_state::msisaac_bg2_textbank_w)); - map(0xf001, 0xf001).nopw(); //??? - map(0xf002, 0xf002).nopw(); //??? + map(0xf000, 0xf000).w(FUNC(msisaac_state::bg2_textbank_w)); + map(0xf001, 0xf001).nopw(); // ??? + map(0xf002, 0xf002).nopw(); // ??? - map(0xf060, 0xf060).w(FUNC(msisaac_state::sound_command_w)); //sound command - map(0xf061, 0xf061).nopw(); /*sound_reset*/ //???? + map(0xf060, 0xf060).w(FUNC(msisaac_state::sound_command_w)); + map(0xf061, 0xf061).nopw(); //sound_reset ???? - map(0xf0a3, 0xf0a3).w(FUNC(msisaac_state::ms_unknown_w)); //???? written in interrupt routine + map(0xf0a3, 0xf0a3).w(FUNC(msisaac_state::unknown_w)); // ???? written in interrupt routine - map(0xf0c0, 0xf0c0).w(FUNC(msisaac_state::msisaac_fg_scrollx_w)); - map(0xf0c1, 0xf0c1).w(FUNC(msisaac_state::msisaac_fg_scrolly_w)); - map(0xf0c2, 0xf0c2).w(FUNC(msisaac_state::msisaac_bg2_scrollx_w)); - map(0xf0c3, 0xf0c3).w(FUNC(msisaac_state::msisaac_bg2_scrolly_w)); - map(0xf0c4, 0xf0c4).w(FUNC(msisaac_state::msisaac_bg_scrollx_w)); - map(0xf0c5, 0xf0c5).w(FUNC(msisaac_state::msisaac_bg_scrolly_w)); + map(0xf0c0, 0xf0c0).w(FUNC(msisaac_state::fg_scrollx_w)); + map(0xf0c1, 0xf0c1).w(FUNC(msisaac_state::fg_scrolly_w)); + map(0xf0c2, 0xf0c2).w(FUNC(msisaac_state::bg2_scrollx_w)); + map(0xf0c3, 0xf0c3).w(FUNC(msisaac_state::bg_scrolly_w<1>)); + map(0xf0c4, 0xf0c4).w(FUNC(msisaac_state::bg_scrollx_w)); + map(0xf0c5, 0xf0c5).w(FUNC(msisaac_state::bg_scrolly_w<0>)); - map(0xf0e0, 0xf0e0).rw(FUNC(msisaac_state::msisaac_mcu_r), FUNC(msisaac_state::msisaac_mcu_w)); - map(0xf0e1, 0xf0e1).r(FUNC(msisaac_state::msisaac_mcu_status_r)); + map(0xf0e0, 0xf0e0).rw(FUNC(msisaac_state::mcu_r), FUNC(msisaac_state::mcu_w)); + map(0xf0e1, 0xf0e1).r(FUNC(msisaac_state::mcu_status_r)); map(0xf080, 0xf080).portr("DSW1"); map(0xf081, 0xf081).portr("DSW2"); @@ -203,43 +537,43 @@ void msisaac_state::msisaac_map(address_map &map) map(0xf084, 0xf084).portr("IN1"); // map(0xf086, 0xf086).portr("IN2"); - map(0xf100, 0xf17f).ram().share("spriteram"); //sprites - map(0xf400, 0xf7ff).ram().w(FUNC(msisaac_state::msisaac_fg_videoram_w)).share("videoram"); - map(0xf800, 0xfbff).ram().w(FUNC(msisaac_state::msisaac_bg2_videoram_w)).share("videoram3"); - map(0xfc00, 0xffff).ram().w(FUNC(msisaac_state::msisaac_bg_videoram_w)).share("videoram2"); -// map(0xf801, 0xf801).w(FUNC(msisaac_state::msisaac_bgcolor_w)); + map(0xf100, 0xf17f).ram().share("spriteram"); + map(0xf400, 0xf7ff).ram().w(FUNC(msisaac_state::fg_videoram_w)).share(m_videoram[0]); + map(0xf800, 0xfbff).ram().w(FUNC(msisaac_state::bg_videoram_w<1>)).share(m_videoram[2]); + map(0xfc00, 0xffff).ram().w(FUNC(msisaac_state::bg_videoram_w<0>)).share(m_videoram[1]); +// map(0xf801, 0xf801).w(FUNC(msisaac_state::bgcolor_w)); // map(0xfc00, 0xfc00).w(FUNC(msisaac_state::flip_screen_w)); -// map(0xfc03, 0xfc04).w(FUNC(msisaac_state::msisaac_coin_counter_w)); +// map(0xfc03, 0xfc04).w(FUNC(msisaac_state::coin_counter_w)); } void msisaac_state::sound_control_0_w(uint8_t data) { - m_snd_ctrl0 = data & 0xff; - //popmessage("SND0 0=%2x 1=%2x", m_snd_ctrl0, m_snd_ctrl1); + m_snd_ctrl[0] = data; + LOGSOUND("SND0 0 = %2x 1 = %2x", m_snd_ctrl[0], m_snd_ctrl[1]); - for(int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { // group1 - m_ta7630->set_channel_volume(m_msm,i, m_snd_ctrl0 & 0xf); + m_ta7630->set_channel_volume(m_msm, i, m_snd_ctrl[0] & 0xf); // group2 - m_ta7630->set_channel_volume(m_msm,i+4, m_snd_ctrl0 >> 4); + m_ta7630->set_channel_volume(m_msm, i + 4, m_snd_ctrl[0] >> 4); } -// m_msm->set_output_gain(0, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */ -// m_msm->set_output_gain(1, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */ -// m_msm->set_output_gain(2, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */ -// m_msm->set_output_gain(3, m_vol_ctrl[m_snd_ctrl0 & 15] / 100.0); /* group1 from msm5232 */ -// m_msm->set_output_gain(4, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */ -// m_msm->set_output_gain(5, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */ -// m_msm->set_output_gain(6, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */ -// m_msm->set_output_gain(7, m_vol_ctrl[(m_snd_ctrl0 >> 4) & 15] / 100.0); /* group2 from msm5232 */ +// m_msm->set_output_gain(0, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232 +// m_msm->set_output_gain(1, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232 +// m_msm->set_output_gain(2, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232 +// m_msm->set_output_gain(3, m_vol_ctrl[m_snd_ctrl[0] & 15] / 100.0); // group1 from msm5232 +// m_msm->set_output_gain(4, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232 +// m_msm->set_output_gain(5, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232 +// m_msm->set_output_gain(6, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232 +// m_msm->set_output_gain(7, m_vol_ctrl[(m_snd_ctrl[0] >> 4) & 15] / 100.0); // group2 from msm5232 } void msisaac_state::sound_control_1_w(uint8_t data) { - m_snd_ctrl1 = data & 0xff; - //popmessage("SND1 0=%2x 1=%2x", m_snd_ctrl0, m_snd_ctrl1); + m_snd_ctrl[1] = data; + LOGSOUND("SND1 0 = %2x 1 = %2x", m_snd_ctrl[0], m_snd_ctrl[1]); } -void msisaac_state::msisaac_sound_map(address_map &map) +void msisaac_state::sound_map(address_map &map) { map(0x0000, 0x3fff).rom(); map(0x4000, 0x47ff).ram(); @@ -251,8 +585,8 @@ void msisaac_state::msisaac_sound_map(address_map &map) map(0xc000, 0xc000).r(m_soundlatch, FUNC(generic_latch_8_device::read)); map(0xc001, 0xc001).w(FUNC(msisaac_state::nmi_enable_w)); map(0xc002, 0xc002).w(FUNC(msisaac_state::nmi_disable_w)); - map(0xc003, 0xc003).nopw(); /*???*/ /* this is NOT mixer_enable */ - map(0xe000, 0xffff).nopr(); /*space for diagnostic ROM (not dumped, not reachable) */ + map(0xc003, 0xc003).nopw(); // ???, this is NOT mixer_enable + map(0xe000, 0xffff).nopr(); // space for diagnostic ROM (not dumped, not reachable) } static INPUT_PORTS_START( msisaac ) @@ -409,13 +743,12 @@ GFXDECODE_END void msisaac_state::machine_start() { - /* video */ + // video save_item(NAME(m_bg2_textbank)); - /* sound */ + // sound save_item(NAME(m_sound_nmi_enable)); save_item(NAME(m_pending_nmi)); - save_item(NAME(m_snd_ctrl0)); - save_item(NAME(m_snd_ctrl1)); + save_item(NAME(m_snd_ctrl)); #ifdef USE_MCU #else @@ -426,15 +759,13 @@ void msisaac_state::machine_start() void msisaac_state::machine_reset() { - //MACHINE_RESET_CALL_MEMBER(ta7630); - - /* video */ + // video m_bg2_textbank = 0; - /* sound */ + // sound m_sound_nmi_enable = 0; m_pending_nmi = 0; - m_snd_ctrl0 = 0; - m_snd_ctrl1 = 0; + m_snd_ctrl[0] = 0; + m_snd_ctrl[1] = 0; #ifdef USE_MCU m_mcu->set_input_line(0, CLEAR_LINE); @@ -446,46 +777,46 @@ void msisaac_state::machine_reset() void msisaac_state::msisaac(machine_config &config) { - /* basic machine hardware */ - Z80(config, m_maincpu, 4000000); - m_maincpu->set_addrmap(AS_PROGRAM, &msisaac_state::msisaac_map); + // basic machine hardware + Z80(config, m_maincpu, 4'000'000); + m_maincpu->set_addrmap(AS_PROGRAM, &msisaac_state::main_map); m_maincpu->set_vblank_int("screen", FUNC(msisaac_state::irq0_line_hold)); - Z80(config, m_audiocpu, 4000000); - m_audiocpu->set_addrmap(AS_PROGRAM, &msisaac_state::msisaac_sound_map); - m_audiocpu->set_vblank_int("screen", FUNC(msisaac_state::irq0_line_hold)); /* source of IRQs is unknown */ + Z80(config, m_audiocpu, 4'000'000); + m_audiocpu->set_addrmap(AS_PROGRAM, &msisaac_state::sound_map); + m_audiocpu->set_vblank_int("screen", FUNC(msisaac_state::irq0_line_hold)); // source of IRQs is unknown #ifdef USE_MCU - M68705(config, "mcu", 8000000/2).set_addrmap(AS_PROGRAM, &msisaac_state::buggychl_mcu_map); /* 4 MHz */ + M68705(config, "mcu", 8'000'000 / 2).set_addrmap(AS_PROGRAM, &msisaac_state::buggychl_mcu_map); // 4 MHz BUGGYCHL_MCU(config, m_bmcu, 0); #endif - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate screen.set_size(32*8, 32*8); screen.set_visarea(0, 32*8-1, 1*8, 31*8-1); - screen.set_screen_update(FUNC(msisaac_state::screen_update_msisaac)); + screen.set_screen_update(FUNC(msisaac_state::screen_update)); screen.set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_msisaac); PALETTE(config, m_palette).set_format(palette_device::xRGB_444, 1024); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); GENERIC_LATCH_8(config, m_soundlatch); TA7630(config, m_ta7630); - AY8910(config, "ay1", 2000000).add_route(ALL_OUTPUTS, "mono", 0.15); + AY8910(config, "ay1", 2'000'000).add_route(ALL_OUTPUTS, "mono", 0.15); // port A/B likely to be TA7630 filters - AY8910(config, "ay2", 2000000).add_route(ALL_OUTPUTS, "mono", 0.15); + AY8910(config, "ay2", 2'000'000).add_route(ALL_OUTPUTS, "mono", 0.15); // port A/B likely to be TA7630 filters - MSM5232(config, m_msm, 2000000); - m_msm->set_capacitors(0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6); /* 0.65 (???) uF capacitors (match the sample, not verified) */ + MSM5232(config, m_msm, 2'000'000); + m_msm->set_capacitors(0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6, 0.65e-6); // 0.65 (???) uF capacitors (match the sample, not verified) m_msm->add_route(0, "mono", 1.0); // pin 28 2'-1 m_msm->add_route(1, "mono", 1.0); // pin 29 4'-1 m_msm->add_route(2, "mono", 1.0); // pin 30 8'-1 @@ -503,16 +834,16 @@ void msisaac_state::msisaac(machine_config &config) /*******************************************************************************/ ROM_START( msisaac ) - ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 main CPU */ + ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 ROM_LOAD( "a34_11.bin", 0x0000, 0x4000, CRC(40819334) SHA1(65352607165043909a09e96c07f7060f6ce087e6) ) ROM_LOAD( "a34_12.bin", 0x4000, 0x4000, CRC(4c50b298) SHA1(5962882ad37ba6990ba2a6312b570f214cd4c103) ) ROM_LOAD( "a34_13.bin", 0x8000, 0x4000, CRC(2e2b09b3) SHA1(daa715282ed9ef2e519e252a684ef28085becabd) ) ROM_LOAD( "a34_10.bin", 0xc000, 0x2000, CRC(a2c53dc1) SHA1(14f23511f92bcfc94447dabe2826555d68bc1caa) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 sound CPU */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 ROM_LOAD( "a34_01.bin", 0x0000, 0x4000, CRC(545e45e7) SHA1(18ddb1ec8809bb62ae1c1068cd16cd3c933bf6ba) ) - ROM_REGION( 0x0800, "cpu2", 0 ) /* 2k for the microcontroller */ + ROM_REGION( 0x0800, "mcu", 0 ) ROM_LOAD( "a34_14.mcu", 0x0000, 0x0800, NO_DUMP ) // I tried following MCUs; none of them work with this game: @@ -534,5 +865,7 @@ ROM_START( msisaac ) ROM_LOAD( "a34_09.bin", 0x6000, 0x2000, CRC(23eb089d) SHA1(fcf48862825bf09ba3718cbade0e163a660e1a68) ) ROM_END +} // anonymous namespace + -GAME( 1985, msisaac, 0, msisaac, msisaac, msisaac_state, empty_init, ROT270, "Taito Corporation", "Metal Soldier Isaac II", MACHINE_UNEMULATED_PROTECTION | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, msisaac, 0, msisaac, msisaac, msisaac_state, empty_init, ROT270, "Taito Corporation", "Metal Soldier Isaac II", MACHINE_UNEMULATED_PROTECTION | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/taito/msisaac.h b/src/mame/taito/msisaac.h deleted file mode 100644 index d65f9e843b1..00000000000 --- a/src/mame/taito/msisaac.h +++ /dev/null @@ -1,116 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Jarek Burczynski -#ifndef MAME_TAITO_MSISAAC_H -#define MAME_TAITO_MSISAAC_H - -#pragma once - -#include "taito68705.h" - -#include "machine/gen_latch.h" -#include "sound/msm5232.h" -#include "sound/ta7630.h" - -#include "emupal.h" -#include "tilemap.h" - - -/* Disabled because the mcu dump is currently unavailable. -AS */ -//#define USE_MCU - -class msisaac_state : public driver_device -{ -public: - msisaac_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_spriteram(*this, "spriteram"), - m_videoram(*this, "videoram"), - m_videoram3(*this, "videoram3"), - m_videoram2(*this, "videoram2"), - m_audiocpu(*this, "audiocpu"), - m_maincpu(*this, "maincpu"), - m_bmcu(*this, "bmcu"), - m_msm(*this, "msm"), - m_ta7630(*this, "ta7630"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_soundlatch(*this, "soundlatch") - { } - - void msisaac(machine_config &config); - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - -private: - /* memory pointers */ - required_shared_ptr m_spriteram; - required_shared_ptr m_videoram; - required_shared_ptr m_videoram3; - required_shared_ptr m_videoram2; - - /* video-related */ - bitmap_ind16 *m_tmp_bitmap1 = nullptr; - bitmap_ind16 *m_tmp_bitmap2 = nullptr; - tilemap_t *m_bg_tilemap = nullptr; - tilemap_t *m_fg_tilemap = nullptr; - tilemap_t *m_bg2_tilemap = nullptr; - int m_bg2_textbank = 0; - - /* sound-related */ - int m_sound_nmi_enable = 0; - int m_pending_nmi = 0; - - /* fake mcu (in msisaac.c) */ -#ifndef USE_MCU - uint8_t m_mcu_val = 0; - uint8_t m_direction = 0; -#endif - - uint8_t m_snd_ctrl0 = 0; - uint8_t m_snd_ctrl1 = 0; - uint8_t m_snd_ctrl2 = 0; - uint8_t m_snd_ctrl3 = 0; - - /* devices */ - required_device m_audiocpu; - required_device m_maincpu; - optional_device m_bmcu; - required_device m_msm; - required_device m_ta7630; - required_device m_gfxdecode; - required_device m_palette; - required_device m_soundlatch; - - void sound_command_w(uint8_t data); - void nmi_disable_w(uint8_t data); - void nmi_enable_w(uint8_t data); - void ms_unknown_w(uint8_t data); - uint8_t msisaac_mcu_r(offs_t offset); - uint8_t msisaac_mcu_status_r(offs_t offset); - void msisaac_mcu_w(offs_t offset, uint8_t data); - void sound_control_1_w(uint8_t data); - void msisaac_fg_scrolly_w(uint8_t data); - void msisaac_fg_scrollx_w(uint8_t data); - void msisaac_bg2_scrolly_w(uint8_t data); - void msisaac_bg2_scrollx_w(uint8_t data); - void msisaac_bg_scrolly_w(uint8_t data); - void msisaac_bg_scrollx_w(uint8_t data); - void msisaac_bg2_textbank_w(uint8_t data); - void msisaac_bg_videoram_w(offs_t offset, uint8_t data); - void msisaac_bg2_videoram_w(offs_t offset, uint8_t data); - void msisaac_fg_videoram_w(offs_t offset, uint8_t data); - void sound_control_0_w(uint8_t data); - TILE_GET_INFO_MEMBER(get_fg_tile_info); - TILE_GET_INFO_MEMBER(get_bg_tile_info); - TILE_GET_INFO_MEMBER(get_bg2_tile_info); - uint32_t screen_update_msisaac(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(nmi_callback); - void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); - void msisaac_map(address_map &map); - void msisaac_sound_map(address_map &map); -}; - -#endif // MAME_TAITO_MSISAAC_H diff --git a/src/mame/taito/msisaac_v.cpp b/src/mame/taito/msisaac_v.cpp deleted file mode 100644 index a75a57a3789..00000000000 --- a/src/mame/taito/msisaac_v.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Jarek Burczynski -/* -* Video Driver for Metal Soldier Isaac II (1985) -*/ - -#include "emu.h" -#include "msisaac.h" - - -/*************************************************************************** - - Callbacks for the TileMap code - -***************************************************************************/ - -TILE_GET_INFO_MEMBER(msisaac_state::get_fg_tile_info) -{ - int tile_number = m_videoram[tile_index]; - tileinfo.set(0, - tile_number, - 0x10, - 0); -} - -TILE_GET_INFO_MEMBER(msisaac_state::get_bg_tile_info) -{ - int tile_number = m_videoram2[tile_index]; - tileinfo.set(1, - 0x100 + tile_number, - 0x30, - 0); -} - -TILE_GET_INFO_MEMBER(msisaac_state::get_bg2_tile_info) -{ - int tile_number = m_videoram3[tile_index]; - - /* graphics 0 or 1 */ - int gfx_b = (m_bg2_textbank >> 3) & 1; - - tileinfo.set(gfx_b, - tile_number, - 0x20, - 0); -} - -/*************************************************************************** - - Start the video hardware emulation. - -***************************************************************************/ - -void msisaac_state::video_start() -{ - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(msisaac_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - - m_bg2_tilemap->set_transparent_pen(0); - m_fg_tilemap->set_transparent_pen(0); -} - - -/*************************************************************************** - - Memory handlers - -***************************************************************************/ - -void msisaac_state::msisaac_fg_scrolly_w(uint8_t data) -{ - m_fg_tilemap->set_scrolly(0, data); -} - -void msisaac_state::msisaac_fg_scrollx_w(uint8_t data) -{ - m_fg_tilemap->set_scrollx(0, 9 + data); -} - -void msisaac_state::msisaac_bg2_scrolly_w(uint8_t data) -{ - m_bg2_tilemap->set_scrolly(0, data); -} - -void msisaac_state::msisaac_bg2_scrollx_w(uint8_t data) -{ - m_bg2_tilemap->set_scrollx(0, 9 + 2 + data); -} - -void msisaac_state::msisaac_bg_scrolly_w(uint8_t data) -{ - m_bg_tilemap->set_scrolly(0, data); -} - -void msisaac_state::msisaac_bg_scrollx_w(uint8_t data) -{ - m_bg_tilemap->set_scrollx(0, 9 + 4 + data); -} - - -#ifdef UNUSED_FUNCTION -void msisaac_state::msisaac_textbank1_w(uint8_t data) -{ - if (textbank1!=data) - { - textbank1 = data; - fg_tilemap->mark_all_dirty(); - } -} -#endif - -void msisaac_state::msisaac_bg2_textbank_w(uint8_t data) -{ - if (m_bg2_textbank != data ) - { - m_bg2_textbank = data; - m_bg2_tilemap->mark_all_dirty(); - - //check if we are correct on this one - if ((data != 8) && (data != 0)) - { - logerror("bg2 control=%2x\n", data); - } - } -} - -void msisaac_state::msisaac_bg_videoram_w(offs_t offset, uint8_t data) -{ - m_videoram2[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); -} - -void msisaac_state::msisaac_bg2_videoram_w(offs_t offset, uint8_t data) -{ - m_videoram3[offset] = data; - m_bg2_tilemap->mark_tile_dirty(offset); -} - -void msisaac_state::msisaac_fg_videoram_w(offs_t offset, uint8_t data) -{ - m_videoram[offset] = data; - m_fg_tilemap->mark_tile_dirty(offset); -} - - -/*************************************************************************** - - Display refresh - -***************************************************************************/ -void msisaac_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - const uint8_t *source = m_spriteram + 32 * 4 - 4; - const uint8_t *finish = m_spriteram; /* ? */ - - while (source >= finish) - { - int sx = source[0]; - int sy = 240 - source[1] - 1; - int attributes = source[2]; - int sprite_number = source[3]; - - int color = (attributes >> 4) & 0xf; - int flipx = (attributes & 0x1); - int flipy = (attributes & 0x2); - - gfx_element *gfx = m_gfxdecode->gfx(2); - - if (attributes & 4) - { - //color = machine().rand() & 15; - gfx = m_gfxdecode->gfx(3); - } - - if (attributes & 8) /* double size sprite */ - { - switch (attributes & 3) - { - case 0: /* flipx==0 && flipy==0 */ - gfx->transpen(bitmap,cliprect, - sprite_number+1,color, - flipx,flipy, - sx,sy-16,0 ); - gfx->transpen(bitmap,cliprect, - sprite_number,color, - flipx,flipy, - sx,sy,0 ); - break; - case 1: /* flipx==1 && flipy==0 */ - gfx->transpen(bitmap,cliprect, - sprite_number+1,color, - flipx,flipy, - sx,sy-16,0 ); - gfx->transpen(bitmap,cliprect, - sprite_number,color, - flipx,flipy, - sx,sy,0 ); - break; - case 2: /* flipx==0 && flipy==1 */ - gfx->transpen(bitmap,cliprect, - sprite_number,color, - flipx,flipy, - sx,sy-16,0 ); - gfx->transpen(bitmap,cliprect, - sprite_number+1,color, - flipx,flipy, - sx,sy,0 ); - break; - case 3: /* flipx==1 && flipy==1 */ - gfx->transpen(bitmap,cliprect, - sprite_number,color, - flipx,flipy, - sx,sy-16,0 ); - gfx->transpen(bitmap,cliprect, - sprite_number+1,color, - flipx,flipy, - sx,sy,0 ); - break; - } - } - else - { - gfx->transpen(bitmap,cliprect, - sprite_number, - color, - flipx,flipy, - sx,sy,0 ); - } - source -= 4; - } -} - -uint32_t msisaac_state::screen_update_msisaac(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - m_bg2_tilemap->draw(screen, bitmap, cliprect, 0, 0); - draw_sprites(bitmap, cliprect); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} -- cgit v1.2.3