diff options
author | angelosa <salese_corp_ltd@email.it> | 2015-06-30 23:22:59 +0200 |
---|---|---|
committer | angelosa <salese_corp_ltd@email.it> | 2015-06-30 23:22:59 +0200 |
commit | db079fd280ec776d686cc414889d304a149eb6e9 (patch) | |
tree | c9bc758b3c20249ea88279607b9f1912a1620da7 | |
parent | de9c38923a440b678bcf4b8918e27e58c61a5457 (diff) |
taitoair.c fixes and changes:
- Very preliminary Framebuffer DMA hook-up, mostly used for Top Landing to show Course Select on screen;
- Fixed analog inputs;
- Fixed color select for 3d;
- Fixed tilemap priority;
(I assume with this we can promote Top Landing as working)
-rw-r--r-- | src/mame/drivers/taitoair.c | 46 | ||||
-rw-r--r-- | src/mame/includes/taitoair.h | 6 | ||||
-rw-r--r-- | src/mame/video/taitoair.c | 139 |
3 files changed, 139 insertions, 52 deletions
diff --git a/src/mame/drivers/taitoair.c b/src/mame/drivers/taitoair.c index e893b439f4c..5dfc0f29f6b 100644 --- a/src/mame/drivers/taitoair.c +++ b/src/mame/drivers/taitoair.c @@ -220,6 +220,13 @@ cpu #2 (PC=00000609): unmapped memory word read from 00006838 & FFFF cpu #2 (PC=0000060E): unmapped memory word read from 0000683A & FFFF ****************************************************************************/ +/*! + @todo - Framebuffer DMA requires palette switch to be selected dynamically, see at first stage Course Select in Top Landing; + - Air Inferno: exception with DIVIDE BY ZERO after some time of gameplay; + - Air Inferno: Expert course has wrong 3d geometry; + - Top Landing: Night stages might have wrong priority for stars-above-sea; + - Input limiters / analog thresholds for both games; + */ #include "emu.h" #include "cpu/z80/z80.h" @@ -370,6 +377,33 @@ WRITE8_MEMBER(taitoair_state::sound_bankswitch_w) membank("z80bank")->set_entry(data & 3); } +/*! + @brief Framebuffer DMA control + @regs [0] x--- ---- ---- ---- copy framebuffer to the screen + [0] --x- ---- ---- ---- unknown, used on POST test + [0] 1001 1111 1111 1111 used by Air Inferno after erase op, erase -> copy? + [0] 0001 1111 1111 1111 erase op? + [1] xxxx xxxx xxxx xxxx fill value? 0xffff by Top Landing, 0x0000 Air Inferno + [2] (unused) + [3] both games uses 0xb7, most likely a register setting. +*/ +WRITE16_MEMBER(taitoair_state::dma_regs_w) +{ + printf("%08x %04x\n",offset,data); + + if(offset == 0 && ACCESSING_BITS_8_15) + { + if(data == 0x1fff) + { + fb_erase_op(); + } + else if(data & 0x8000) + { + /*! @todo it also flushes current palette. */ + fb_copy_op(); + } + } +} /*********************************************************** MEMORY STRUCTURES @@ -382,7 +416,7 @@ static ADDRESS_MAP_START( airsys_map, AS_PROGRAM, 16, taitoair_state ) AM_RANGE(0x180000, 0x187fff) AM_RAM_WRITE(airsys_gradram_w) AM_SHARE("gradram") /* "gradiation ram (0/1)" */ AM_RANGE(0x188000, 0x189fff) AM_MIRROR(0x2000) AM_RAM_WRITE(airsys_paletteram16_w) AM_SHARE("paletteram") AM_RANGE(0x800000, 0x820fff) AM_DEVREADWRITE("tc0080vco", tc0080vco_device, word_r, word_w) /* tilemaps, sprites */ -// AM_RANGE(0x906000, 0x906007) AM_RAM // DMA? + AM_RANGE(0x906000, 0x906007) AM_WRITE(dma_regs_w) // DMA? AM_RANGE(0x908000, 0x90ffff) AM_RAM AM_SHARE("line_ram") /* "line ram" */ AM_RANGE(0x910000, 0x91ffff) AM_RAM AM_SHARE("dsp_ram") /* "dsp common ram" (TMS320C25) */ AM_RANGE(0x980000, 0x98000f) AM_RAM AM_SHARE("tc0430grw") /* TC0430GRW roz transform coefficients */ @@ -585,10 +619,10 @@ static INPUT_PORTS_START( topland ) PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Z ) PORT_MINMAX(0x0080,0x007f) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) PORT_REVERSE PORT_START(STICK2_PORT_TAG) - PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0xf800,0x07ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) + PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1) PORT_START(STICK3_PORT_TAG) - PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0xf800,0x07ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) + PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1) INPUT_PORTS_END static INPUT_PORTS_START( ainferno ) @@ -645,10 +679,10 @@ static INPUT_PORTS_START( ainferno ) PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Z ) PORT_MINMAX(0x0080,0x007f) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) PORT_REVERSE PORT_START(STICK2_PORT_TAG) - PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0xf800,0x7ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) + PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1) PORT_START(STICK3_PORT_TAG) - PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0xf800,0x7ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) + PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1) INPUT_PORTS_END @@ -953,6 +987,6 @@ ROM_END /* ( YEAR NAME PARENT MACHINE INPUT INIT MONITOR COMPANY FULLNAME */ -GAME( 1988, topland, 0, airsys, topland, driver_device, 0, ROT0, "Taito Corporation Japan", "Top Landing (World)", GAME_NOT_WORKING ) +GAME( 1988, topland, 0, airsys, topland, driver_device, 0, ROT0, "Taito Corporation Japan", "Top Landing (World)", GAME_IMPERFECT_GRAPHICS ) GAME( 1990, ainferno, 0, airsys, ainferno, driver_device, 0, ROT0, "Taito America Corporation", "Air Inferno (US)", GAME_NOT_WORKING ) GAME( 1990, ainfernoj,ainferno, airsys, ainferno, driver_device, 0, ROT0, "Taito Corporation Japan", "Air Inferno (Japan)", GAME_NOT_WORKING ) diff --git a/src/mame/includes/taitoair.h b/src/mame/includes/taitoair.h index b5536f6cfa9..356801eede6 100644 --- a/src/mame/includes/taitoair.h +++ b/src/mame/includes/taitoair.h @@ -119,6 +119,7 @@ public: DECLARE_READ16_MEMBER(stick2_input_r); DECLARE_WRITE8_MEMBER(sound_bankswitch_w); DECLARE_WRITE16_MEMBER(dsp_flags_w); + DECLARE_WRITE16_MEMBER(dma_regs_w); virtual void machine_start(); virtual void machine_reset(); @@ -126,7 +127,10 @@ public: UINT32 screen_update_taitoair(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int start_offset ); - + void fb_copy_op(void); + void fb_fill_op(void); + void fb_erase_op(void); + void fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16 header, INT32 x1, INT32 x2, INT32 sl1, INT32 sl2, INT32 y1, INT32 y2, INT32 *nx1, INT32 *nx2 ); void fill_poly( bitmap_ind16 &bitmap, const rectangle &cliprect, const struct taitoair_poly *q ); int projectEyeCoordToScreen(float* projectionMatrix,const int Res,INT16* eyePoint3d,int type); diff --git a/src/mame/video/taitoair.c b/src/mame/video/taitoair.c index fc231c09c69..600beaf048c 100644 --- a/src/mame/video/taitoair.c +++ b/src/mame/video/taitoair.c @@ -259,24 +259,26 @@ void taitoair_state::fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect if (xx2 > cliprect.max_x) xx2 = cliprect.max_x; - if(header & 0x4000 || machine().input().code_pressed(KEYCODE_Q)) + if(header & 0x4000 && machine().input().code_pressed(KEYCODE_Q)) { base_color = machine().rand() & 0x3fff; grad_col = 0; } - else if(header & 0x40) - { - /* Non-terrain elements are colored with this. */ - base_color = (header & 0x3f) + 0x340; - grad_col = 0; - } - else + else if(m_paletteram[(header & 0xff)+0x300] & 0x8000) { /* Terrain elements, with a gradient applied. */ /*! @todo it's unknown if gradient color applies by global screen Y coordinate or there's a calculation to somewhere ... */ base_color = ((header & 0x3f) * 0x80) + 0x2040; + if(header & 0x3fe0) + base_color = machine().rand() & 0x3fff; grad_col = (y1 >> 3) & 0x3f; } + else + { + /* Non-terrain elements are colored with this. */ + base_color = (header & 0xff) + 0x300; + grad_col = 0; + } while (xx1 <= xx2) { @@ -388,8 +390,84 @@ void taitoair_state::fill_poly( bitmap_ind16 &bitmap, const rectangle &cliprect, dsp handlers ***************************************************************************/ -/* - TODO: still don't know how this works. It calls three values (0x1fff-0x5fff-0xdfff), for two or three offsets. +void taitoair_state::fb_copy_op() +{ + /*! @todo declare once */ + rectangle cliprect; + + /* printf("%04x -> %d\n",data,offset); */ + + cliprect.min_x = 0; + cliprect.min_y = 3*16; + cliprect.max_x = m_screen->width() - 1; + cliprect.max_y = m_screen->height() - 1; + + /* clear screen fb */ + m_framebuffer[1]->fill(0, cliprect); + /* copy buffer fb into screen fb (at this stage we are ready to draw) */ + copybitmap_trans(*m_framebuffer[1], *m_framebuffer[0], 0, 0, 0, 0, cliprect, 0); + /* now clear buffer fb */ + m_framebuffer[0]->fill(0, cliprect); +} + +void taitoair_state::fb_erase_op() +{ + /*! @todo declare once */ + rectangle cliprect; + + /* printf("%04x -> %d\n",data,offset); */ + + cliprect.min_x = 0; + cliprect.min_y = 3*16; + cliprect.max_x = m_screen->width() - 1; + cliprect.max_y = m_screen->height() - 1; + + m_framebuffer[0]->fill(0, cliprect); + m_framebuffer[1]->fill(0, cliprect); +} + +void taitoair_state::fb_fill_op() +{ + /*! @todo declare once */ + rectangle cliprect; + + /* printf("%04x -> %d\n",data,offset); */ + + cliprect.min_x = 0; + cliprect.min_y = 3*16; + cliprect.max_x = m_screen->width() - 1; + cliprect.max_y = m_screen->height() - 1; + + if (m_line_ram[0x3fff]) + { + int adr = 0x3fff; + + while (adr >= 0 && m_line_ram[adr] && m_line_ram[adr] != 0x4000) + { + int pcount = 0; + m_q.header = m_line_ram[adr--]; + while (pcount < TAITOAIR_POLY_MAX_PT && adr >= 1 && !(m_line_ram[adr] & 0xc000)) + { + m_q.p[pcount].y = m_line_ram[adr--] + 3 * 16; + m_q.p[pcount].x = m_line_ram[adr--]; + pcount++; + } + adr--; + m_q.pcount = pcount; + if (!(m_line_ram[adr] & 0x8000)) + { + m_q.header |= 0x4000; + logerror("special poly at %04x\n", adr); + while(adr >= 0 && !(m_line_ram[adr] & 0xc000)) + adr--; + } + fill_poly(*m_framebuffer[0], cliprect, &m_q); + } + } +} + +/*! + @todo still don't know how this works. It calls three values (0x1fff-0x5fff-0xdfff), for two or three offsets. In theory this should fit into framebuffer draw, display, clear and swap in some way. */ WRITE16_MEMBER(taitoair_state::dsp_flags_w) @@ -407,43 +485,13 @@ WRITE16_MEMBER(taitoair_state::dsp_flags_w) /* clear and copy operation if offset is 0x3001 */ if(offset == 1) { - /* clear screen fb */ - m_framebuffer[1]->fill(0, cliprect); - /* copy buffer fb into screen fb (at this stage we are ready to draw) */ - copybitmap_trans(*m_framebuffer[1], *m_framebuffer[0], 0, 0, 0, 0, cliprect, 0); - /* now clear buffer fb */ - m_framebuffer[0]->fill(0, cliprect); + fb_copy_op(); } /* if offset 0x3001 OR 0x3002 we put data in the buffer fb */ if(offset) { - if (m_line_ram[0x3fff]) - { - int adr = 0x3fff; - - while (adr >= 0 && m_line_ram[adr] && m_line_ram[adr] != 0x4000) - { - int pcount = 0; - m_q.header = m_line_ram[adr--]; - while (pcount < TAITOAIR_POLY_MAX_PT && adr >= 1 && !(m_line_ram[adr] & 0xc000)) - { - m_q.p[pcount].y = m_line_ram[adr--] + 3 * 16; - m_q.p[pcount].x = m_line_ram[adr--]; - pcount++; - } - adr--; - m_q.pcount = pcount; - if (!(m_line_ram[adr] & 0x8000)) - { - m_q.header |= 0x4000; - logerror("special poly at %04x\n", adr); - while(adr >= 0 && !(m_line_ram[adr] & 0xc000)) - adr--; - } - fill_poly(*m_framebuffer[0], cliprect, &m_q); - } - } + fb_fill_op(); } } } @@ -505,13 +553,14 @@ UINT32 taitoair_state::screen_update_taitoair(screen_device &screen, bitmap_ind1 } - m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 0, 0, 0); copybitmap_trans(bitmap, *m_framebuffer[1], 0, 0, 0, 0, cliprect, 0); + m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 0, 0, 0); + sprite_ptr = draw_sprites(bitmap, cliprect); - - m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 1, 0, 0); + + m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 1, 0, 0); m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 2, 0, 0); |