segaic24.cpp: added xhout and xvout register callbacks, and hooked them up to Model 2 driver, fixing 3d viewport positions [Angelo Salese]

This commit is contained in:
angelosa 2018-03-03 13:11:54 +01:00
parent ce34c6cc75
commit 3ec82506b5
5 changed files with 64 additions and 13 deletions

View File

@ -1436,9 +1436,9 @@ ADDRESS_MAP_START(model2_state::model2_base_mem)
AM_RANGE(0x00f00000, 0x00f0000f) AM_READWRITE(timers_r, timers_w)
AM_RANGE(0x01000000, 0x0100ffff) AM_DEVREADWRITE16("tile", segas24_tile_device, tile_r, tile_w,0xffffffff) AM_MIRROR(0x110000)
AM_RANGE(0x01020000, 0x01020003) AM_WRITENOP AM_MIRROR(0x100000) // Unknown, always 0
AM_RANGE(0x01040000, 0x01040003) AM_WRITENOP AM_MIRROR(0x100000) // Horizontal synchronization register
AM_RANGE(0x01060000, 0x01060003) AM_WRITENOP AM_MIRROR(0x100000) // Vertical synchronization register
AM_RANGE(0x01020000, 0x01020003) AM_WRITENOP AM_MIRROR(0x100000) // ABSEL, always 0
AM_RANGE(0x01040000, 0x01040003) AM_DEVWRITE16("tile", segas24_tile_device, xhout_w, 0x0000ffff) AM_MIRROR(0x100000) // Horizontal synchronization register
AM_RANGE(0x01060000, 0x01060003) AM_DEVWRITE16("tile", segas24_tile_device, xvout_w, 0x0000ffff) AM_MIRROR(0x100000) // Vertical synchronization register
AM_RANGE(0x01070000, 0x01070003) AM_WRITENOP AM_MIRROR(0x100000) // Video synchronization switch
AM_RANGE(0x01080000, 0x010fffff) AM_DEVREADWRITE16("tile", segas24_tile_device, char_r, char_w,0xffffffff) AM_MIRROR(0x100000)
@ -2256,7 +2256,9 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(model2_state::model2_screen)
MCFG_S24TILE_DEVICE_ADD("tile", 0x3fff)
MCFG_S24TILE_DEVICE_PALETTE("palette")
MCFG_S24TILE_XHOUT_CALLBACK(WRITE16(model2_state, horizontal_sync_w))
MCFG_S24TILE_XVOUT_CALLBACK(WRITE16(model2_state, vertical_sync_w))
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
// TODO: from System 24, might not be accurate for Model 2

View File

@ -180,7 +180,9 @@ public:
DECLARE_READ32_MEMBER(model2_serial_r);
DECLARE_WRITE32_MEMBER(model2o_serial_w);
DECLARE_WRITE32_MEMBER(model2_serial_w);
DECLARE_WRITE16_MEMBER(horizontal_sync_w);
DECLARE_WRITE16_MEMBER(vertical_sync_w);
void raster_init(memory_region *texture_rom);
void geo_init(memory_region *polygon_rom);
DECLARE_READ32_MEMBER(render_mode_r);
@ -276,7 +278,8 @@ private:
bool m_render_unk;
bool m_render_mode;
int16 m_crtc_xoffset, m_crtc_yoffset;
uint32_t *geo_process_command( geo_state *geo, uint32_t opcode, uint32_t *input, bool *end_code );
// geo commands
uint32_t *geo_nop( geo_state *geo, uint32_t opcode, uint32_t *input );
@ -315,7 +318,6 @@ private:
// inliners
inline void model2_3d_project( triangle *tri );
};
/*****************************
@ -489,12 +491,16 @@ public:
m_renderfuncs[5] = &model2_renderer::model2_3d_render_5;
m_renderfuncs[6] = &model2_renderer::model2_3d_render_6;
m_renderfuncs[7] = &model2_renderer::model2_3d_render_7;
m_xoffs = 90;
m_yoffs = -8;
}
bitmap_rgb32& destmap() { return m_destmap; }
void model2_3d_render(triangle *tri, const rectangle &cliprect);
void set_xoffset(int16 xoffs) { m_xoffs = xoffs; }
void set_yoffset(int16 yoffs) { m_yoffs = yoffs; }
/* checker = 0, textured = 0, transparent = 0 */
#define MODEL2_FUNC 0
#define MODEL2_FUNC_NAME model2_3d_render_0
@ -556,6 +562,7 @@ public:
private:
model2_state& m_state;
bitmap_rgb32 m_destmap;
int16_t m_xoffs,m_yoffs;
};
typedef model2_renderer::vertex_t poly_vertex;

View File

@ -819,7 +819,7 @@ void model2_renderer::model2_3d_render(triangle *tri, const rectangle &cliprect)
renderer = (tri->texheader[0] >> 13) & 7;
/* calculate and clip to viewport */
rectangle vp(tri->viewport[0] - 8, tri->viewport[2] - 8, (384-tri->viewport[3])+90, (384-tri->viewport[1])+90);
rectangle vp(tri->viewport[0] + m_xoffs, tri->viewport[2] + m_xoffs, (384-tri->viewport[3]) + m_yoffs, (384-tri->viewport[1]) + m_yoffs);
// TODO: this seems to be more accurate but it breaks in some cases
//rectangle vp(tri->viewport[0] - 8, tri->viewport[2] - tri->viewport[0], tri->viewport[1] - 90, tri->viewport[3] - tri->viewport[1]);
vp &= cliprect;
@ -899,6 +899,20 @@ void model2_renderer::model2_3d_render(triangle *tri, const rectangle &cliprect)
(8,90) (504,90)
*/
WRITE16_MEMBER(model2_state::horizontal_sync_w)
{
m_crtc_xoffset = 84 + (int16_t)data;
// printf("H %04x %d %d\n",data,(int16_t)data,m_crtc_xoffset);
m_poly->set_xoffset(m_crtc_xoffset);
}
WRITE16_MEMBER(model2_state::vertical_sync_w)
{
m_crtc_yoffset = 130 + (int16_t)data;
// printf("V %04x %d %d\n",data,(int16_t)data,m_crtc_yoffset);
m_poly->set_yoffset(m_crtc_yoffset);
}
/* 3D Rasterizer projection: projects a triangle into screen coordinates */
inline void model2_state::model2_3d_project( triangle *tri )
{
@ -907,8 +921,8 @@ inline void model2_state::model2_3d_project( triangle *tri )
for( i = 0; i < 3; i++ )
{
/* project the vertices */
tri->v[i].x = -8 + tri->center[0] + (tri->v[i].x / (1.0f+tri->v[i].pz));
tri->v[i].y = ((384 - tri->center[1])+90) - (tri->v[i].y / (1.0f+tri->v[i].pz));
tri->v[i].x = m_crtc_xoffset + tri->center[0] + (tri->v[i].x / (1.0f+tri->v[i].pz));
tri->v[i].y = ((384 - tri->center[1])+m_crtc_yoffset) - (tri->v[i].y / (1.0f+tri->v[i].pz));
}
}

View File

@ -28,6 +28,8 @@ segas24_tile_device::segas24_tile_device(const machine_config &mconfig, const ch
: device_t(mconfig, S24TILE, tag, owner, clock)
, device_gfx_interface(mconfig, *this)
, char_gfx_index(0)
, m_xhout_write_cb(*this)
, m_xvout_write_cb(*this)
{
}
@ -76,7 +78,9 @@ void segas24_tile_device::device_start()
char_ram = std::make_unique<uint16_t[]>(0x80000/2);
tile_ram = std::make_unique<uint16_t[]>(0x10000/2);
m_xhout_write_cb.resolve_safe();
m_xvout_write_cb.resolve_safe();
tile_layer[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(segas24_tile_device::tile_info_0s),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
tile_layer[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(segas24_tile_device::tile_info_0w),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
tile_layer[2] = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(segas24_tile_device::tile_info_1s),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
@ -549,6 +553,16 @@ WRITE16_MEMBER(segas24_tile_device::char_w)
gfx(char_gfx_index)->mark_dirty(offset / 16);
}
WRITE16_MEMBER(segas24_tile_device::xhout_w)
{
m_xhout_write_cb(data);
}
WRITE16_MEMBER(segas24_tile_device::xvout_w)
{
m_xvout_write_cb(data);
}
segas24_sprite_device::segas24_sprite_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, S24SPRITE, tag, owner, clock)
{

View File

@ -20,10 +20,16 @@
#define MCFG_S24MIXER_DEVICE_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, S24MIXER, 0)
#define MCFG_S24TILE_DEVICE_PALETTE(_palette_tag) \
MCFG_GFX_PALETTE(_palette_tag)
#define MCFG_S24TILE_XHOUT_CALLBACK(_write) \
devcb = &downcast<segas24_tile_device &>(*device).set_xhout_write_callback(DEVCB_##_write);
#define MCFG_S24TILE_XVOUT_CALLBACK(_write) \
devcb = &downcast<segas24_tile_device &>(*device).set_xvout_write_callback(DEVCB_##_write);
class segas24_tile_device : public device_t, public device_gfx_interface
{
friend class segas24_tile_config;
@ -38,10 +44,15 @@ public:
DECLARE_WRITE16_MEMBER(tile_w);
DECLARE_READ16_MEMBER(char_r);
DECLARE_WRITE16_MEMBER(char_w);
DECLARE_WRITE16_MEMBER(xhout_w);
DECLARE_WRITE16_MEMBER(xvout_w);
void draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int pri, int flags);
void draw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int layer, int pri, int flags);
template <class Object> devcb_base &set_xhout_write_callback(Object &&cb) { return m_xhout_write_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_xvout_write_callback(Object &&cb) { return m_xvout_write_cb.set_callback(std::forward<Object>(cb)); }
protected:
virtual void device_start() override;
@ -71,6 +82,9 @@ private:
template<class _BitmapClass>
void draw_common(screen_device &screen, _BitmapClass &bitmap, const rectangle &cliprect, int layer, int pri, int flags);
devcb_write16 m_xhout_write_cb;
devcb_write16 m_xvout_write_cb;
};
class segas24_sprite_device : public device_t