mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
Split Taito TC0780FPA into its own device [Ville Linde]
This commit is contained in:
parent
b4329313f9
commit
0df7787f16
@ -3662,6 +3662,8 @@ files {
|
||||
MAME_DIR .. "src/mame/video/tc0110pcr.h",
|
||||
MAME_DIR .. "src/mame/video/tc0180vcu.cpp",
|
||||
MAME_DIR .. "src/mame/video/tc0180vcu.h",
|
||||
MAME_DIR .. "src/mame/video/tc0780fpa.cpp",
|
||||
MAME_DIR .. "src/mame/video/tc0780fpa.h",
|
||||
}
|
||||
|
||||
createMAMEProjects(_target, _subtarget, "tatsumi")
|
||||
|
@ -860,63 +860,17 @@ WRITE16_MEMBER(taitojc_state::dsp_rom_w)
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(taitojc_state::dsp_texture_w)
|
||||
{
|
||||
int index;
|
||||
int x, y;
|
||||
|
||||
x = (m_dsp_tex_offset >> 0 & 0x1f) | (m_dsp_tex_offset >> 5 & 0x20);
|
||||
y = (m_dsp_tex_offset >> 5 & 0x1f) | (m_dsp_tex_offset >> 6 & 0x20);
|
||||
|
||||
index = (((m_texture_y * 32) + y) * 2048) + ((m_texture_x * 32) + x);
|
||||
m_texture[index] = data & 0xff;
|
||||
|
||||
m_dsp_tex_offset++;
|
||||
}
|
||||
|
||||
READ16_MEMBER(taitojc_state::dsp_texaddr_r)
|
||||
{
|
||||
return m_dsp_tex_address;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(taitojc_state::dsp_texaddr_w)
|
||||
{
|
||||
m_dsp_tex_address = data;
|
||||
|
||||
m_texture_x = (((data >> 0) & 0x1f) << 1) | ((data >> 12) & 0x1);
|
||||
m_texture_y = (((data >> 5) & 0x1f) << 1) | ((data >> 13) & 0x1);
|
||||
|
||||
m_dsp_tex_offset = 0;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(taitojc_state::dsp_polygon_fifo_w)
|
||||
{
|
||||
assert (m_polygon_fifo_ptr < TAITOJC_POLYGON_FIFO_SIZE); // never happens
|
||||
m_polygon_fifo[m_polygon_fifo_ptr++] = data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(taitojc_state::dsp_unk2_w)
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
taitojc_clear_frame();
|
||||
m_renderer->render_polygons(m_polygon_fifo.get(), m_polygon_fifo_ptr);
|
||||
|
||||
m_polygon_fifo_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( tms_program_map, AS_PROGRAM, 16, taitojc_state )
|
||||
AM_RANGE(0x0000, 0x1fff) AM_RAM AM_MIRROR(0x4000)
|
||||
AM_RANGE(0x6000, 0x7fff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( tms_data_map, AS_DATA, 16, taitojc_state )
|
||||
AM_RANGE(0x6a01, 0x6a02) AM_WRITE(dsp_unk2_w)
|
||||
AM_RANGE(0x6a01, 0x6a02) AM_DEVWRITE("tc0780fpa", tc0780fpa_device, render_w)
|
||||
AM_RANGE(0x6a11, 0x6a12) AM_NOP // same as 0x6a01..02 for the second renderer chip?
|
||||
AM_RANGE(0x6b20, 0x6b20) AM_WRITE(dsp_polygon_fifo_w)
|
||||
AM_RANGE(0x6b22, 0x6b22) AM_WRITE(dsp_texture_w)
|
||||
AM_RANGE(0x6b23, 0x6b23) AM_READWRITE(dsp_texaddr_r, dsp_texaddr_w)
|
||||
AM_RANGE(0x6b20, 0x6b20) AM_DEVWRITE("tc0780fpa", tc0780fpa_device, poly_fifo_w)
|
||||
AM_RANGE(0x6b22, 0x6b22) AM_DEVWRITE("tc0780fpa", tc0780fpa_device, tex_w)
|
||||
AM_RANGE(0x6b23, 0x6b23) AM_DEVREADWRITE("tc0780fpa", tc0780fpa_device, tex_addr_r, tex_addr_w)
|
||||
AM_RANGE(0x6c00, 0x6c01) AM_READWRITE(dsp_rom_r, dsp_rom_w)
|
||||
AM_RANGE(0x7000, 0x7002) AM_WRITE(dsp_math_projection_w)
|
||||
AM_RANGE(0x7010, 0x7012) AM_WRITE(dsp_math_intersection_w)
|
||||
@ -1098,13 +1052,7 @@ void taitojc_state::machine_reset()
|
||||
m_mcu_data_main = 0;
|
||||
m_mcu_data_hc11 = 0;
|
||||
|
||||
m_texture_x = 0;
|
||||
m_texture_y = 0;
|
||||
|
||||
m_dsp_rom_pos = 0;
|
||||
m_dsp_tex_address = 0;
|
||||
m_dsp_tex_offset = 0;
|
||||
m_polygon_fifo_ptr = 0;
|
||||
|
||||
memset(m_viewport_data, 0, sizeof(m_viewport_data));
|
||||
memset(m_projection_data, 0, sizeof(m_projection_data));
|
||||
@ -1117,17 +1065,12 @@ void taitojc_state::machine_reset()
|
||||
void taitojc_state::machine_start()
|
||||
{
|
||||
// register for savestates
|
||||
save_item(NAME(m_texture_x));
|
||||
save_item(NAME(m_texture_y));
|
||||
save_item(NAME(m_dsp_rom_pos));
|
||||
save_item(NAME(m_dsp_tex_address));
|
||||
save_item(NAME(m_dsp_tex_offset));
|
||||
save_item(NAME(m_first_dsp_reset));
|
||||
save_item(NAME(m_viewport_data));
|
||||
save_item(NAME(m_projection_data));
|
||||
save_item(NAME(m_intersection_data));
|
||||
save_item(NAME(m_gfx_index));
|
||||
save_item(NAME(m_polygon_fifo_ptr));
|
||||
|
||||
save_item(NAME(m_mcu_comm_main));
|
||||
save_item(NAME(m_mcu_comm_hc11));
|
||||
@ -1177,6 +1120,8 @@ static MACHINE_CONFIG_START( taitojc, taitojc_state )
|
||||
|
||||
MCFG_PALETTE_ADD("palette", 32768)
|
||||
|
||||
MCFG_DEVICE_ADD("tc0780fpa", TC0780FPA, 0)
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_FRAGMENT_ADD(taito_en_sound)
|
||||
MACHINE_CONFIG_END
|
||||
@ -1225,8 +1170,6 @@ READ16_MEMBER(taitojc_state::dendego2_dsp_idle_skip_r)
|
||||
|
||||
DRIVER_INIT_MEMBER(taitojc_state,taitojc)
|
||||
{
|
||||
m_polygon_fifo = std::make_unique<UINT16[]>(TAITOJC_POLYGON_FIFO_SIZE);
|
||||
|
||||
m_has_dsp_hack = 1;
|
||||
|
||||
if (DSP_IDLESKIP)
|
||||
|
@ -530,6 +530,7 @@ WRITE16_MEMBER(taitopjc_state::tms_dspshare_w)
|
||||
|
||||
static ADDRESS_MAP_START( tms_program_map, AS_PROGRAM, 16, taitopjc_state )
|
||||
AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("user2", 0)
|
||||
AM_RANGE(0x5000, 0xefff) AM_ROM AM_REGION("user2", 0xa000)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( tms_data_map, AS_DATA, 16, taitopjc_state )
|
||||
|
@ -6,42 +6,9 @@
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include "video/poly.h"
|
||||
#include "video/tc0780fpa.h"
|
||||
#include "machine/taitoio.h"
|
||||
|
||||
#define TAITOJC_POLYGON_FIFO_SIZE 0x20000
|
||||
|
||||
struct taitojc_polydata
|
||||
{
|
||||
int tex_base_x;
|
||||
int tex_base_y;
|
||||
int tex_wrap_x;
|
||||
int tex_wrap_y;
|
||||
};
|
||||
|
||||
class taitojc_renderer : public poly_manager<float, taitojc_polydata, 6, 10000>
|
||||
{
|
||||
public:
|
||||
taitojc_renderer(running_machine &machine, bitmap_ind16 *fb, bitmap_ind16 *zb, const UINT8 *texture_ram)
|
||||
: poly_manager<float, taitojc_polydata, 6, 10000>(machine)
|
||||
{
|
||||
m_framebuffer = fb;
|
||||
m_zbuffer = zb;
|
||||
m_texture = texture_ram;
|
||||
}
|
||||
|
||||
void render_solid_scan(INT32 scanline, const extent_t &extent, const taitojc_polydata &extradata, int threadid);
|
||||
void render_shade_scan(INT32 scanline, const extent_t &extent, const taitojc_polydata &extradata, int threadid);
|
||||
void render_texture_scan(INT32 scanline, const extent_t &extent, const taitojc_polydata &extradata, int threadid);
|
||||
|
||||
void render_polygons(UINT16 *polygon_fifo, int length);
|
||||
|
||||
private:
|
||||
bitmap_ind16 *m_framebuffer;
|
||||
bitmap_ind16 *m_zbuffer;
|
||||
const UINT8 *m_texture;
|
||||
};
|
||||
|
||||
class taitojc_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -60,7 +27,8 @@ public:
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_analog_ports(*this, "AN")
|
||||
m_analog_ports(*this, "AN"),
|
||||
m_tc0780fpa(*this, "tc0780fpa")
|
||||
{
|
||||
m_mcu_output = 0;
|
||||
m_speed_meter = 0;
|
||||
@ -85,33 +53,21 @@ public:
|
||||
required_device<palette_device> m_palette;
|
||||
optional_ioport_array<8> m_analog_ports;
|
||||
|
||||
taitojc_renderer *m_renderer;
|
||||
|
||||
int m_texture_x;
|
||||
int m_texture_y;
|
||||
required_device<tc0780fpa_device> m_tc0780fpa;
|
||||
|
||||
UINT32 m_dsp_rom_pos;
|
||||
UINT16 m_dsp_tex_address;
|
||||
UINT16 m_dsp_tex_offset;
|
||||
|
||||
int m_first_dsp_reset;
|
||||
INT16 m_viewport_data[3];
|
||||
INT16 m_projection_data[3];
|
||||
INT16 m_intersection_data[3];
|
||||
|
||||
std::unique_ptr<UINT8[]> m_texture;
|
||||
bitmap_ind16 m_framebuffer;
|
||||
bitmap_ind16 m_zbuffer;
|
||||
|
||||
int m_gfx_index;
|
||||
|
||||
UINT32 *m_char_ram;
|
||||
UINT32 *m_tile_ram;
|
||||
tilemap_t *m_tilemap;
|
||||
|
||||
std::unique_ptr<UINT16[]> m_polygon_fifo;
|
||||
int m_polygon_fifo_ptr;
|
||||
|
||||
UINT8 m_mcu_comm_main;
|
||||
UINT8 m_mcu_comm_hc11;
|
||||
UINT8 m_mcu_data_main;
|
||||
|
@ -318,14 +318,6 @@ void taitojc_state::video_start()
|
||||
|
||||
/* create the char set (gfx will then be updated dynamically from RAM) */
|
||||
m_gfxdecode->set_gfx(m_gfx_index, global_alloc(gfx_element(m_palette, taitojc_char_layout, (UINT8 *)m_char_ram, 0, m_palette->entries() / 16, 0)));
|
||||
|
||||
m_texture = std::make_unique<UINT8[]>(0x400000);
|
||||
|
||||
m_screen->register_screen_bitmap(m_framebuffer);
|
||||
m_screen->register_screen_bitmap(m_zbuffer);
|
||||
|
||||
/* create renderer */
|
||||
m_renderer = auto_alloc(machine(), taitojc_renderer(machine(), &m_framebuffer, &m_zbuffer, m_texture.get()));
|
||||
}
|
||||
|
||||
UINT32 taitojc_state::screen_update_taitojc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
@ -338,7 +330,7 @@ UINT32 taitojc_state::screen_update_taitojc(screen_device &screen, bitmap_ind16
|
||||
draw_object_bank(bitmap, cliprect, 2, 0);
|
||||
|
||||
// 3D layer
|
||||
copybitmap_trans(bitmap, m_framebuffer, 0, 0, 0, 0, cliprect, 0);
|
||||
m_tc0780fpa->draw(bitmap, cliprect);
|
||||
|
||||
// high priority objects
|
||||
draw_object_bank(bitmap, cliprect, 0, 1);
|
||||
@ -375,396 +367,3 @@ UINT32 taitojc_state::screen_update_dendego(screen_device &screen, bitmap_ind16
|
||||
|
||||
return screen_update_taitojc(screen, bitmap, cliprect);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void taitojc_renderer::render_solid_scan(INT32 scanline, const extent_t &extent, const taitojc_polydata &extradata, int threadid)
|
||||
{
|
||||
float z = extent.param[0].start;
|
||||
int color = extent.param[1].start;
|
||||
float dz = extent.param[0].dpdx;
|
||||
UINT16 *fb = &m_framebuffer->pix16(scanline);
|
||||
UINT16 *zb = &m_zbuffer->pix16(scanline);
|
||||
|
||||
for (int x = extent.startx; x < extent.stopx; x++)
|
||||
{
|
||||
int iz = (int)z & 0xffff;
|
||||
|
||||
if (iz <= zb[x])
|
||||
{
|
||||
fb[x] = color;
|
||||
zb[x] = iz;
|
||||
}
|
||||
|
||||
z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
void taitojc_renderer::render_shade_scan(INT32 scanline, const extent_t &extent, const taitojc_polydata &extradata, int threadid)
|
||||
{
|
||||
float z = extent.param[0].start;
|
||||
float color = extent.param[1].start;
|
||||
float dz = extent.param[0].dpdx;
|
||||
float dcolor = extent.param[1].dpdx;
|
||||
UINT16 *fb = &m_framebuffer->pix16(scanline);
|
||||
UINT16 *zb = &m_zbuffer->pix16(scanline);
|
||||
|
||||
for (int x = extent.startx; x < extent.stopx; x++)
|
||||
{
|
||||
int ic = (int)color & 0xffff;
|
||||
int iz = (int)z & 0xffff;
|
||||
|
||||
if (iz <= zb[x])
|
||||
{
|
||||
fb[x] = ic;
|
||||
zb[x] = iz;
|
||||
}
|
||||
|
||||
color += dcolor;
|
||||
z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
void taitojc_renderer::render_texture_scan(INT32 scanline, const extent_t &extent, const taitojc_polydata &extradata, int threadid)
|
||||
{
|
||||
float z = extent.param[0].start;
|
||||
float u = extent.param[1].start;
|
||||
float v = extent.param[2].start;
|
||||
float color = extent.param[3].start;
|
||||
float dz = extent.param[0].dpdx;
|
||||
float du = extent.param[1].dpdx;
|
||||
float dv = extent.param[2].dpdx;
|
||||
float dcolor = extent.param[3].dpdx;
|
||||
UINT16 *fb = &m_framebuffer->pix16(scanline);
|
||||
UINT16 *zb = &m_zbuffer->pix16(scanline);
|
||||
int tex_wrap_x = extradata.tex_wrap_x;
|
||||
int tex_wrap_y = extradata.tex_wrap_y;
|
||||
int tex_base_x = extradata.tex_base_x;
|
||||
int tex_base_y = extradata.tex_base_y;
|
||||
|
||||
for (int x = extent.startx; x < extent.stopx; x++)
|
||||
{
|
||||
int iu, iv;
|
||||
UINT8 texel;
|
||||
int palette = ((int)color & 0x7f) << 8;
|
||||
int iz = (int)z & 0xffff;
|
||||
|
||||
if (!tex_wrap_x)
|
||||
{
|
||||
iu = ((int)u >> 4) & 0x7ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
iu = (tex_base_x + (((int)u >> 4) & 0x3f)) & 0x7ff;
|
||||
}
|
||||
|
||||
if (!tex_wrap_y)
|
||||
{
|
||||
iv = ((int)v >> 4) & 0x7ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
iv = (tex_base_y + (((int)v >> 4) & 0x3f)) & 0x7ff;
|
||||
}
|
||||
|
||||
texel = m_texture[(iv * 2048) + iu];
|
||||
|
||||
if (iz <= zb[x] && texel != 0)
|
||||
{
|
||||
fb[x] = palette | texel;
|
||||
zb[x] = iz;
|
||||
}
|
||||
|
||||
u += du;
|
||||
v += dv;
|
||||
color += dcolor;
|
||||
z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
void taitojc_renderer::render_polygons(UINT16 *polygon_fifo, int length)
|
||||
{
|
||||
const rectangle visarea = machine().first_screen()->visible_area();
|
||||
vertex_t vert[4];
|
||||
int i;
|
||||
int ptr;
|
||||
|
||||
ptr = 0;
|
||||
while (ptr < length)
|
||||
{
|
||||
UINT16 cmd = polygon_fifo[ptr++];
|
||||
|
||||
switch (cmd & 0x7)
|
||||
{
|
||||
// screen global clipping for 3d(?)
|
||||
case 0x00:
|
||||
{
|
||||
UINT16 min_x,min_y,min_z,max_x,max_y,max_z;
|
||||
|
||||
min_x = polygon_fifo[ptr+1];
|
||||
min_y = polygon_fifo[ptr+0];
|
||||
min_z = polygon_fifo[ptr+2];
|
||||
max_x = polygon_fifo[ptr+4];
|
||||
max_y = polygon_fifo[ptr+3];
|
||||
max_z = polygon_fifo[ptr+5];
|
||||
|
||||
/* let's check if we need to implement this ... */
|
||||
if(min_x != 0 || min_y != 0 || min_z != 0 || max_x != 512 || max_y != 400 || max_z != 0x7fff)
|
||||
{
|
||||
printf("CMD %04x\n",cmd);
|
||||
printf("MIN Y %04x\n",polygon_fifo[ptr+0]);
|
||||
printf("MIN X %04x\n",polygon_fifo[ptr+1]);
|
||||
printf("MIN Z %04x\n",polygon_fifo[ptr+2]);
|
||||
printf("MAX Y %04x\n",polygon_fifo[ptr+3]);
|
||||
printf("MAX X %04x\n",polygon_fifo[ptr+4]);
|
||||
printf("MAX Z %04x\n",polygon_fifo[ptr+5]);
|
||||
}
|
||||
ptr += 6;
|
||||
break;
|
||||
}
|
||||
|
||||
// Gouraud Shaded Triangle (Landing Gear)
|
||||
case 0x01:
|
||||
{
|
||||
// 0x00: Command ID (0x0001)
|
||||
// 0x01: Vertex 1 color
|
||||
// 0x02: Vertex 1 Y
|
||||
// 0x03: Vertex 1 X
|
||||
// 0x04: Vertex 1 Z
|
||||
// 0x05: Vertex 2 color
|
||||
// 0x06: Vertex 2 Y
|
||||
// 0x07: Vertex 2 X
|
||||
// 0x08: Vertex 2 Z
|
||||
// 0x09: Vertex 3 color
|
||||
// 0x0a: Vertex 3 Y
|
||||
// 0x0b: Vertex 3 X
|
||||
// 0x0c: Vertex 3 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD1: ");
|
||||
for (i=0; i < 0x0c; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
{
|
||||
vert[i].p[1] = polygon_fifo[ptr++];
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000)
|
||||
{
|
||||
if (vert[0].p[1] == vert[1].p[1] &&
|
||||
vert[1].p[1] == vert[2].p[1])
|
||||
{
|
||||
// optimization: all colours the same -> render solid
|
||||
render_triangle(visarea, render_delegate(FUNC(taitojc_renderer::render_solid_scan), this), 2, vert[0], vert[1], vert[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
render_triangle(visarea, render_delegate(FUNC(taitojc_renderer::render_shade_scan), this), 2, vert[0], vert[1], vert[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Textured Triangle
|
||||
case 0x03:
|
||||
{
|
||||
// 0x00: Command ID (0x0003)
|
||||
// 0x01: Texture base
|
||||
// 0x02: Vertex 1 Palette
|
||||
// 0x03: Vertex 1 V
|
||||
// 0x04: Vertex 1 U
|
||||
// 0x05: Vertex 1 Y
|
||||
// 0x06: Vertex 1 X
|
||||
// 0x07: Vertex 1 Z
|
||||
// 0x08: Vertex 2 Palette
|
||||
// 0x09: Vertex 2 V
|
||||
// 0x0a: Vertex 2 U
|
||||
// 0x0b: Vertex 2 Y
|
||||
// 0x0c: Vertex 2 X
|
||||
// 0x0d: Vertex 2 Z
|
||||
// 0x0e: Vertex 3 Palette
|
||||
// 0x0f: Vertex 3 V
|
||||
// 0x10: Vertex 3 U
|
||||
// 0x11: Vertex 3 Y
|
||||
// 0x12: Vertex 3 X
|
||||
// 0x13: Vertex 3 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD3: ");
|
||||
for (i=0; i < 0x13; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
taitojc_polydata &extra = object_data_alloc();
|
||||
UINT16 texbase = polygon_fifo[ptr++];
|
||||
|
||||
extra.tex_base_x = ((texbase >> 0) & 0xff) << 4;
|
||||
extra.tex_base_y = ((texbase >> 8) & 0xff) << 4;
|
||||
|
||||
extra.tex_wrap_x = (cmd & 0xc0) ? 1 : 0;
|
||||
extra.tex_wrap_y = (cmd & 0x30) ? 1 : 0;
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
{
|
||||
vert[i].p[3] = polygon_fifo[ptr++] + 0.5; // palette
|
||||
vert[i].p[2] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[1] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000)
|
||||
{
|
||||
render_triangle(visarea, render_delegate(FUNC(taitojc_renderer::render_texture_scan), this), 4, vert[0], vert[1], vert[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Gouraud shaded Quad
|
||||
case 0x04:
|
||||
{
|
||||
// 0x00: Command ID (0x0004)
|
||||
// 0x01: Vertex 1 color
|
||||
// 0x02: Vertex 1 Y
|
||||
// 0x03: Vertex 1 X
|
||||
// 0x04: Vertex 1 Z
|
||||
// 0x05: Vertex 2 color
|
||||
// 0x06: Vertex 2 Y
|
||||
// 0x07: Vertex 2 X
|
||||
// 0x08: Vertex 2 Z
|
||||
// 0x09: Vertex 3 color
|
||||
// 0x0a: Vertex 3 Y
|
||||
// 0x0b: Vertex 3 X
|
||||
// 0x0c: Vertex 3 Z
|
||||
// 0x0d: Vertex 4 color
|
||||
// 0x0e: Vertex 4 Y
|
||||
// 0x0f: Vertex 4 X
|
||||
// 0x10: Vertex 4 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD4: ");
|
||||
for (i=0; i < 0x10; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
vert[i].p[1] = polygon_fifo[ptr++];
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000 && vert[3].p[0] < 0x8000)
|
||||
{
|
||||
if (vert[0].p[1] == vert[1].p[1] &&
|
||||
vert[1].p[1] == vert[2].p[1] &&
|
||||
vert[2].p[1] == vert[3].p[1])
|
||||
{
|
||||
// optimization: all colours the same -> render solid
|
||||
render_polygon<4>(visarea, render_delegate(FUNC(taitojc_renderer::render_solid_scan), this), 2, vert);
|
||||
}
|
||||
else
|
||||
{
|
||||
render_polygon<4>(visarea, render_delegate(FUNC(taitojc_renderer::render_shade_scan), this), 2, vert);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Textured Quad
|
||||
case 0x06:
|
||||
{
|
||||
// 0x00: Command ID (0x0006)
|
||||
// 0x01: Texture base
|
||||
// 0x02: Vertex 1 Palette
|
||||
// 0x03: Vertex 1 V
|
||||
// 0x04: Vertex 1 U
|
||||
// 0x05: Vertex 1 Y
|
||||
// 0x06: Vertex 1 X
|
||||
// 0x07: Vertex 1 Z
|
||||
// 0x08: Vertex 2 Palette
|
||||
// 0x09: Vertex 2 V
|
||||
// 0x0a: Vertex 2 U
|
||||
// 0x0b: Vertex 2 Y
|
||||
// 0x0c: Vertex 2 X
|
||||
// 0x0d: Vertex 2 Z
|
||||
// 0x0e: Vertex 3 Palette
|
||||
// 0x0f: Vertex 3 V
|
||||
// 0x10: Vertex 3 U
|
||||
// 0x11: Vertex 3 Y
|
||||
// 0x12: Vertex 3 X
|
||||
// 0x13: Vertex 3 Z
|
||||
// 0x14: Vertex 4 Palette
|
||||
// 0x15: Vertex 4 V
|
||||
// 0x16: Vertex 4 U
|
||||
// 0x17: Vertex 4 Y
|
||||
// 0x18: Vertex 4 X
|
||||
// 0x19: Vertex 4 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD6: ");
|
||||
for (i=0; i < 0x19; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
taitojc_polydata &extra = object_data_alloc();
|
||||
UINT16 texbase = polygon_fifo[ptr++];
|
||||
|
||||
extra.tex_base_x = ((texbase >> 0) & 0xff) << 4;
|
||||
extra.tex_base_y = ((texbase >> 8) & 0xff) << 4;
|
||||
|
||||
extra.tex_wrap_x = (cmd & 0xc0) ? 1 : 0;
|
||||
extra.tex_wrap_y = (cmd & 0x30) ? 1 : 0;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
vert[i].p[3] = polygon_fifo[ptr++] + 0.5; // palette
|
||||
vert[i].p[2] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[1] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000 && vert[3].p[0] < 0x8000)
|
||||
{
|
||||
render_polygon<4>(visarea, render_delegate(FUNC(taitojc_renderer::render_texture_scan), this), 4, vert);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
printf("render_polygons: unknown command %04X %d\n", cmd,ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait("Finished render");
|
||||
}
|
||||
|
||||
void taitojc_state::taitojc_clear_frame()
|
||||
{
|
||||
m_framebuffer.fill(0, m_screen->visible_area());
|
||||
m_zbuffer.fill(0xffff, m_screen->visible_area());
|
||||
}
|
||||
|
534
src/mame/video/tc0780fpa.cpp
Normal file
534
src/mame/video/tc0780fpa.cpp
Normal file
@ -0,0 +1,534 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Ville Linde, Angelo Salese, hap
|
||||
|
||||
// Taito TC0780FPA Polygon Renderer
|
||||
|
||||
#include "emu.h"
|
||||
#include "tc0780fpa.h"
|
||||
|
||||
|
||||
#define POLY_FIFO_SIZE 0x20000
|
||||
|
||||
|
||||
tc0780fpa_renderer::tc0780fpa_renderer(device_t &parent, screen_device &screen, const UINT8 *texture_ram)
|
||||
: poly_manager<float, tc0780fpa_polydata, 6, 10000>(screen)
|
||||
{
|
||||
int width = screen.width();
|
||||
int height = screen.height();
|
||||
|
||||
m_fb = std::make_unique<bitmap_ind16>(width, height);
|
||||
m_zb = std::make_unique<bitmap_ind16>(width, height);
|
||||
|
||||
m_texture = texture_ram;
|
||||
|
||||
m_cliprect = screen.cliprect();
|
||||
|
||||
// save state
|
||||
parent.save_item(NAME(*m_fb));
|
||||
parent.save_item(NAME(*m_zb));
|
||||
}
|
||||
|
||||
void tc0780fpa_renderer::clear_frame()
|
||||
{
|
||||
m_fb->fill(0, m_cliprect);
|
||||
m_zb->fill(0xffff, m_cliprect);
|
||||
}
|
||||
|
||||
void tc0780fpa_renderer::draw(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap_trans(bitmap, *m_fb, 0, 0, 0, 0, cliprect, 0);
|
||||
}
|
||||
|
||||
void tc0780fpa_renderer::render_solid_scan(INT32 scanline, const extent_t &extent, const tc0780fpa_polydata &extradata, int threadid)
|
||||
{
|
||||
float z = extent.param[0].start;
|
||||
int color = extent.param[1].start;
|
||||
float dz = extent.param[0].dpdx;
|
||||
UINT16 *fb = &m_fb->pix16(scanline);
|
||||
UINT16 *zb = &m_zb->pix16(scanline);
|
||||
|
||||
for (int x = extent.startx; x < extent.stopx; x++)
|
||||
{
|
||||
int iz = (int)z & 0xffff;
|
||||
|
||||
if (iz <= zb[x])
|
||||
{
|
||||
fb[x] = color;
|
||||
zb[x] = iz;
|
||||
}
|
||||
|
||||
z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
void tc0780fpa_renderer::render_shade_scan(INT32 scanline, const extent_t &extent, const tc0780fpa_polydata &extradata, int threadid)
|
||||
{
|
||||
float z = extent.param[0].start;
|
||||
float color = extent.param[1].start;
|
||||
float dz = extent.param[0].dpdx;
|
||||
float dcolor = extent.param[1].dpdx;
|
||||
UINT16 *fb = &m_fb->pix16(scanline);
|
||||
UINT16 *zb = &m_zb->pix16(scanline);
|
||||
|
||||
for (int x = extent.startx; x < extent.stopx; x++)
|
||||
{
|
||||
int ic = (int)color & 0xffff;
|
||||
int iz = (int)z & 0xffff;
|
||||
|
||||
if (iz <= zb[x])
|
||||
{
|
||||
fb[x] = ic;
|
||||
zb[x] = iz;
|
||||
}
|
||||
|
||||
color += dcolor;
|
||||
z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
void tc0780fpa_renderer::render_texture_scan(INT32 scanline, const extent_t &extent, const tc0780fpa_polydata &extradata, int threadid)
|
||||
{
|
||||
float z = extent.param[0].start;
|
||||
float u = extent.param[1].start;
|
||||
float v = extent.param[2].start;
|
||||
float color = extent.param[3].start;
|
||||
float dz = extent.param[0].dpdx;
|
||||
float du = extent.param[1].dpdx;
|
||||
float dv = extent.param[2].dpdx;
|
||||
float dcolor = extent.param[3].dpdx;
|
||||
UINT16 *fb = &m_fb->pix16(scanline);
|
||||
UINT16 *zb = &m_zb->pix16(scanline);
|
||||
int tex_wrap_x = extradata.tex_wrap_x;
|
||||
int tex_wrap_y = extradata.tex_wrap_y;
|
||||
int tex_base_x = extradata.tex_base_x;
|
||||
int tex_base_y = extradata.tex_base_y;
|
||||
|
||||
for (int x = extent.startx; x < extent.stopx; x++)
|
||||
{
|
||||
int iu, iv;
|
||||
UINT8 texel;
|
||||
int palette = ((int)color & 0x7f) << 8;
|
||||
int iz = (int)z & 0xffff;
|
||||
|
||||
if (!tex_wrap_x)
|
||||
{
|
||||
iu = ((int)u >> 4) & 0x7ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
iu = (tex_base_x + (((int)u >> 4) & 0x3f)) & 0x7ff;
|
||||
}
|
||||
|
||||
if (!tex_wrap_y)
|
||||
{
|
||||
iv = ((int)v >> 4) & 0x7ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
iv = (tex_base_y + (((int)v >> 4) & 0x3f)) & 0x7ff;
|
||||
}
|
||||
|
||||
texel = m_texture[(iv * 2048) + iu];
|
||||
|
||||
if (iz <= zb[x] && texel != 0)
|
||||
{
|
||||
fb[x] = palette | texel;
|
||||
zb[x] = iz;
|
||||
}
|
||||
|
||||
u += du;
|
||||
v += dv;
|
||||
color += dcolor;
|
||||
z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
void tc0780fpa_renderer::render_polygons(UINT16 *polygon_fifo, int length)
|
||||
{
|
||||
vertex_t vert[4];
|
||||
int i;
|
||||
int ptr;
|
||||
|
||||
ptr = 0;
|
||||
while (ptr < length)
|
||||
{
|
||||
UINT16 cmd = polygon_fifo[ptr++];
|
||||
|
||||
switch (cmd & 0x7)
|
||||
{
|
||||
// screen global clipping for 3d(?)
|
||||
case 0x00:
|
||||
{
|
||||
UINT16 min_x,min_y,min_z,max_x,max_y,max_z;
|
||||
|
||||
min_x = polygon_fifo[ptr+1];
|
||||
min_y = polygon_fifo[ptr+0];
|
||||
min_z = polygon_fifo[ptr+2];
|
||||
max_x = polygon_fifo[ptr+4];
|
||||
max_y = polygon_fifo[ptr+3];
|
||||
max_z = polygon_fifo[ptr+5];
|
||||
|
||||
/* let's check if we need to implement this ... */
|
||||
if(min_x != 0 || min_y != 0 || min_z != 0 || max_x != 512 || max_y != 400 || max_z != 0x7fff)
|
||||
{
|
||||
printf("CMD %04x\n",cmd);
|
||||
printf("MIN Y %04x\n",polygon_fifo[ptr+0]);
|
||||
printf("MIN X %04x\n",polygon_fifo[ptr+1]);
|
||||
printf("MIN Z %04x\n",polygon_fifo[ptr+2]);
|
||||
printf("MAX Y %04x\n",polygon_fifo[ptr+3]);
|
||||
printf("MAX X %04x\n",polygon_fifo[ptr+4]);
|
||||
printf("MAX Z %04x\n",polygon_fifo[ptr+5]);
|
||||
}
|
||||
ptr += 6;
|
||||
break;
|
||||
}
|
||||
|
||||
// Gouraud Shaded Triangle (Landing Gear)
|
||||
case 0x01:
|
||||
{
|
||||
// 0x00: Command ID (0x0001)
|
||||
// 0x01: Vertex 1 color
|
||||
// 0x02: Vertex 1 Y
|
||||
// 0x03: Vertex 1 X
|
||||
// 0x04: Vertex 1 Z
|
||||
// 0x05: Vertex 2 color
|
||||
// 0x06: Vertex 2 Y
|
||||
// 0x07: Vertex 2 X
|
||||
// 0x08: Vertex 2 Z
|
||||
// 0x09: Vertex 3 color
|
||||
// 0x0a: Vertex 3 Y
|
||||
// 0x0b: Vertex 3 X
|
||||
// 0x0c: Vertex 3 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD1: ");
|
||||
for (i=0; i < 0x0c; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
{
|
||||
vert[i].p[1] = polygon_fifo[ptr++];
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000)
|
||||
{
|
||||
if (vert[0].p[1] == vert[1].p[1] &&
|
||||
vert[1].p[1] == vert[2].p[1])
|
||||
{
|
||||
// optimization: all colours the same -> render solid
|
||||
render_triangle(m_cliprect, render_delegate(FUNC(tc0780fpa_renderer::render_solid_scan), this), 2, vert[0], vert[1], vert[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
render_triangle(m_cliprect, render_delegate(FUNC(tc0780fpa_renderer::render_shade_scan), this), 2, vert[0], vert[1], vert[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Textured Triangle
|
||||
case 0x03:
|
||||
{
|
||||
// 0x00: Command ID (0x0003)
|
||||
// 0x01: Texture base
|
||||
// 0x02: Vertex 1 Palette
|
||||
// 0x03: Vertex 1 V
|
||||
// 0x04: Vertex 1 U
|
||||
// 0x05: Vertex 1 Y
|
||||
// 0x06: Vertex 1 X
|
||||
// 0x07: Vertex 1 Z
|
||||
// 0x08: Vertex 2 Palette
|
||||
// 0x09: Vertex 2 V
|
||||
// 0x0a: Vertex 2 U
|
||||
// 0x0b: Vertex 2 Y
|
||||
// 0x0c: Vertex 2 X
|
||||
// 0x0d: Vertex 2 Z
|
||||
// 0x0e: Vertex 3 Palette
|
||||
// 0x0f: Vertex 3 V
|
||||
// 0x10: Vertex 3 U
|
||||
// 0x11: Vertex 3 Y
|
||||
// 0x12: Vertex 3 X
|
||||
// 0x13: Vertex 3 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD3: ");
|
||||
for (i=0; i < 0x13; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
tc0780fpa_polydata &extra = object_data_alloc();
|
||||
UINT16 texbase = polygon_fifo[ptr++];
|
||||
|
||||
extra.tex_base_x = ((texbase >> 0) & 0xff) << 4;
|
||||
extra.tex_base_y = ((texbase >> 8) & 0xff) << 4;
|
||||
|
||||
extra.tex_wrap_x = (cmd & 0xc0) ? 1 : 0;
|
||||
extra.tex_wrap_y = (cmd & 0x30) ? 1 : 0;
|
||||
|
||||
for (i=0; i < 3; i++)
|
||||
{
|
||||
vert[i].p[3] = polygon_fifo[ptr++] + 0.5; // palette
|
||||
vert[i].p[2] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[1] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000)
|
||||
{
|
||||
render_triangle(m_cliprect, render_delegate(FUNC(tc0780fpa_renderer::render_texture_scan), this), 4, vert[0], vert[1], vert[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Gouraud shaded Quad
|
||||
case 0x04:
|
||||
{
|
||||
// 0x00: Command ID (0x0004)
|
||||
// 0x01: Vertex 1 color
|
||||
// 0x02: Vertex 1 Y
|
||||
// 0x03: Vertex 1 X
|
||||
// 0x04: Vertex 1 Z
|
||||
// 0x05: Vertex 2 color
|
||||
// 0x06: Vertex 2 Y
|
||||
// 0x07: Vertex 2 X
|
||||
// 0x08: Vertex 2 Z
|
||||
// 0x09: Vertex 3 color
|
||||
// 0x0a: Vertex 3 Y
|
||||
// 0x0b: Vertex 3 X
|
||||
// 0x0c: Vertex 3 Z
|
||||
// 0x0d: Vertex 4 color
|
||||
// 0x0e: Vertex 4 Y
|
||||
// 0x0f: Vertex 4 X
|
||||
// 0x10: Vertex 4 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD4: ");
|
||||
for (i=0; i < 0x10; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
vert[i].p[1] = polygon_fifo[ptr++];
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000 && vert[3].p[0] < 0x8000)
|
||||
{
|
||||
if (vert[0].p[1] == vert[1].p[1] &&
|
||||
vert[1].p[1] == vert[2].p[1] &&
|
||||
vert[2].p[1] == vert[3].p[1])
|
||||
{
|
||||
// optimization: all colours the same -> render solid
|
||||
render_polygon<4>(m_cliprect, render_delegate(FUNC(tc0780fpa_renderer::render_solid_scan), this), 2, vert);
|
||||
}
|
||||
else
|
||||
{
|
||||
render_polygon<4>(m_cliprect, render_delegate(FUNC(tc0780fpa_renderer::render_shade_scan), this), 2, vert);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Textured Quad
|
||||
case 0x06:
|
||||
{
|
||||
// 0x00: Command ID (0x0006)
|
||||
// 0x01: Texture base
|
||||
// 0x02: Vertex 1 Palette
|
||||
// 0x03: Vertex 1 V
|
||||
// 0x04: Vertex 1 U
|
||||
// 0x05: Vertex 1 Y
|
||||
// 0x06: Vertex 1 X
|
||||
// 0x07: Vertex 1 Z
|
||||
// 0x08: Vertex 2 Palette
|
||||
// 0x09: Vertex 2 V
|
||||
// 0x0a: Vertex 2 U
|
||||
// 0x0b: Vertex 2 Y
|
||||
// 0x0c: Vertex 2 X
|
||||
// 0x0d: Vertex 2 Z
|
||||
// 0x0e: Vertex 3 Palette
|
||||
// 0x0f: Vertex 3 V
|
||||
// 0x10: Vertex 3 U
|
||||
// 0x11: Vertex 3 Y
|
||||
// 0x12: Vertex 3 X
|
||||
// 0x13: Vertex 3 Z
|
||||
// 0x14: Vertex 4 Palette
|
||||
// 0x15: Vertex 4 V
|
||||
// 0x16: Vertex 4 U
|
||||
// 0x17: Vertex 4 Y
|
||||
// 0x18: Vertex 4 X
|
||||
// 0x19: Vertex 4 Z
|
||||
|
||||
#if 0
|
||||
printf("CMD6: ");
|
||||
for (i=0; i < 0x19; i++)
|
||||
{
|
||||
printf("%04X ", polygon_fifo[ptr+i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
tc0780fpa_polydata &extra = object_data_alloc();
|
||||
UINT16 texbase = polygon_fifo[ptr++];
|
||||
|
||||
extra.tex_base_x = ((texbase >> 0) & 0xff) << 4;
|
||||
extra.tex_base_y = ((texbase >> 8) & 0xff) << 4;
|
||||
|
||||
extra.tex_wrap_x = (cmd & 0xc0) ? 1 : 0;
|
||||
extra.tex_wrap_y = (cmd & 0x30) ? 1 : 0;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
vert[i].p[3] = polygon_fifo[ptr++] + 0.5; // palette
|
||||
vert[i].p[2] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[1] = (UINT16)(polygon_fifo[ptr++]);
|
||||
vert[i].y = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].x = (INT16)(polygon_fifo[ptr++]);
|
||||
vert[i].p[0] = (UINT16)(polygon_fifo[ptr++]);
|
||||
}
|
||||
|
||||
if (vert[0].p[0] < 0x8000 && vert[1].p[0] < 0x8000 && vert[2].p[0] < 0x8000 && vert[3].p[0] < 0x8000)
|
||||
{
|
||||
render_polygon<4>(m_cliprect, render_delegate(FUNC(tc0780fpa_renderer::render_texture_scan), this), 4, vert);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
printf("tc0780fpa::render_polygons(): unknown command %04X %d\n", cmd,ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait("Finished render");
|
||||
}
|
||||
|
||||
|
||||
|
||||
const device_type TC0780FPA = &device_creator<tc0780fpa_device>;
|
||||
|
||||
tc0780fpa_device::tc0780fpa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, TC0780FPA, "TC0780FPA Polygon Renderer", tag, owner, clock, "tc0780fpa", __FILE__),
|
||||
device_video_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void tc0780fpa_device::device_config_complete()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void tc0780fpa_device::device_start()
|
||||
{
|
||||
m_texture = std::make_unique<UINT8[]>(0x400000);
|
||||
m_poly_fifo = std::make_unique<UINT16[]>(POLY_FIFO_SIZE);
|
||||
|
||||
m_renderer = auto_alloc(machine(), tc0780fpa_renderer(*this, *m_screen, m_texture.get()));
|
||||
|
||||
save_pointer(NAME(m_texture.get()), 0x400000);
|
||||
save_pointer(NAME(m_poly_fifo.get()), POLY_FIFO_SIZE);
|
||||
save_item(NAME(m_poly_fifo_ptr));
|
||||
save_item(NAME(m_tex_address));
|
||||
save_item(NAME(m_tex_offset));
|
||||
save_item(NAME(m_texbase_x));
|
||||
save_item(NAME(m_texbase_y));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void tc0780fpa_device::device_reset()
|
||||
{
|
||||
m_poly_fifo_ptr = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_stop - device-specific stop
|
||||
//-------------------------------------------------
|
||||
|
||||
void tc0780fpa_device::device_stop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
DEVICE HANDLERS
|
||||
*****************************************************************************/
|
||||
|
||||
READ16_MEMBER(tc0780fpa_device::tex_addr_r)
|
||||
{
|
||||
return m_tex_address;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(tc0780fpa_device::tex_addr_w)
|
||||
{
|
||||
m_tex_address = data;
|
||||
|
||||
m_texbase_x = (((data >> 0) & 0x1f) << 1) | ((data >> 12) & 0x1);
|
||||
m_texbase_y = (((data >> 5) & 0x1f) << 1) | ((data >> 13) & 0x1);
|
||||
|
||||
m_tex_offset = 0;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(tc0780fpa_device::tex_w)
|
||||
{
|
||||
int x = ((m_tex_offset >> 0) & 0x1f) | ((m_tex_offset >> 5) & 0x20);
|
||||
int y = ((m_tex_offset >> 5) & 0x1f) | ((m_tex_offset >> 6) & 0x20);
|
||||
|
||||
int index = (((m_texbase_y * 32) + y) * 2048) + ((m_texbase_x * 32) + x);
|
||||
m_texture[index] = data & 0xff;
|
||||
|
||||
m_tex_offset++;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(tc0780fpa_device::poly_fifo_w)
|
||||
{
|
||||
assert (m_poly_fifo_ptr < POLY_FIFO_SIZE); // never happens
|
||||
m_poly_fifo[m_poly_fifo_ptr++] = data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(tc0780fpa_device::render_w)
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
m_renderer->clear_frame();
|
||||
m_renderer->render_polygons(m_poly_fifo.get(), m_poly_fifo_ptr);
|
||||
|
||||
m_poly_fifo_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void tc0780fpa_device::draw(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_renderer->draw(bitmap, cliprect);
|
||||
}
|
80
src/mame/video/tc0780fpa.h
Normal file
80
src/mame/video/tc0780fpa.h
Normal file
@ -0,0 +1,80 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Ville Linde, Angelo Salese, hap
|
||||
|
||||
#pragma once
|
||||
#ifndef __TC0780FPA_H__
|
||||
#define __TC0780FPA_H__
|
||||
|
||||
#include "video/poly.h"
|
||||
|
||||
|
||||
struct tc0780fpa_polydata
|
||||
{
|
||||
int tex_base_x;
|
||||
int tex_base_y;
|
||||
int tex_wrap_x;
|
||||
int tex_wrap_y;
|
||||
};
|
||||
|
||||
|
||||
class tc0780fpa_renderer : public poly_manager<float, tc0780fpa_polydata, 6, 10000>
|
||||
{
|
||||
public:
|
||||
tc0780fpa_renderer(device_t &parent, screen_device &screen, const UINT8 *texture_ram);
|
||||
~tc0780fpa_renderer() {}
|
||||
|
||||
void render_solid_scan(INT32 scanline, const extent_t &extent, const tc0780fpa_polydata &extradata, int threadid);
|
||||
void render_shade_scan(INT32 scanline, const extent_t &extent, const tc0780fpa_polydata &extradata, int threadid);
|
||||
void render_texture_scan(INT32 scanline, const extent_t &extent, const tc0780fpa_polydata &extradata, int threadid);
|
||||
|
||||
void render_polygons(UINT16 *polygon_fifo, int length);
|
||||
void draw(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void clear_frame();
|
||||
|
||||
private:
|
||||
std::unique_ptr<bitmap_ind16> m_fb;
|
||||
std::unique_ptr<bitmap_ind16> m_zb;
|
||||
const UINT8 *m_texture;
|
||||
|
||||
rectangle m_cliprect;
|
||||
};
|
||||
|
||||
|
||||
class tc0780fpa_device : public device_t, public device_video_interface
|
||||
{
|
||||
public:
|
||||
tc0780fpa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
~tc0780fpa_device() {}
|
||||
|
||||
void draw(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void texture_write(offs_t address, UINT8 data);
|
||||
|
||||
DECLARE_READ16_MEMBER(tex_addr_r);
|
||||
DECLARE_WRITE16_MEMBER(tex_addr_w);
|
||||
DECLARE_WRITE16_MEMBER(tex_w);
|
||||
DECLARE_WRITE16_MEMBER(poly_fifo_w);
|
||||
DECLARE_WRITE16_MEMBER(render_w);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_stop() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<UINT8[]> m_texture;
|
||||
std::unique_ptr<UINT16[]> m_poly_fifo;
|
||||
int m_poly_fifo_ptr;
|
||||
|
||||
tc0780fpa_renderer *m_renderer;
|
||||
|
||||
UINT16 m_tex_address;
|
||||
UINT16 m_tex_offset;
|
||||
int m_texbase_x;
|
||||
int m_texbase_y;
|
||||
};
|
||||
|
||||
extern const device_type TC0780FPA;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user