ainferno: Little gift for Kale (nw)

This commit is contained in:
Olivier Galibert 2015-06-29 15:12:58 +02:00
parent e282409f9e
commit a6231b342f
3 changed files with 130 additions and 176 deletions

View File

@ -412,33 +412,95 @@ ADDRESS_MAP_END
/********************************** TMS32025 ********************************/
/*
Air Inferno:
WRITE16_MEMBER(taitoair_state::dsp_test_start_w)
{
m_dsp_test_object_type = data;
m_dsp_test_or_clip = 0;
m_dsp_test_and_clip = 0xf;
}
write to 0x3404 - almost always 0x00fd / 0xff38 (253, -200)
write to 0x3408 /
WRITE16_MEMBER(taitoair_state::dsp_test_x_w)
{
m_dsp_test_x = data;
}
write to 0x341b - May not be numeric - it's weird. stays stable,
then freaks out just before "quad: unknown value 0066"
This function seems to break things up into different polygon
'classes'
WRITE16_MEMBER(taitoair_state::dsp_test_y_w)
{
m_dsp_test_y = data;
}
write to 0x3418 - X value
write to 0x3419 - Y value
write to 0x341a - Z value
read to 0x341b, puts data to internal RAM 0x380 - 0x384 - 0x388 - 0x38c
WRITE16_MEMBER(taitoair_state::dsp_test_z_w)
{
m_dsp_test_z = data;
}
checks 0x341c - if != to 0 then skip ... ?
checks 0x341d - if == to 0 then skip ... ?
READ16_MEMBER(taitoair_state::dsp_test_point_r)
{
UINT16 r = 0;
if(m_dsp_test_x < -m_dsp_test_z)
r |= 1;
if(m_dsp_test_x > m_dsp_test_z)
r |= 2;
if(m_dsp_test_y < -m_dsp_test_z)
r |= 4;
if(m_dsp_test_y > m_dsp_test_z)
r |= 8;
write to 0x3405 ; X value
write to 0x3409 ; Y value
write to 0x3406 ; Z value
write to 0x340a ; Z value
read to 0x340b, puts to line RAM (y) with offset + 0x160
read to 0x3407, puts to line RAM (x) with offset + 0x5d
m_dsp_test_or_clip |= r;
m_dsp_test_and_clip &= r;
return r;
}
READ16_MEMBER(taitoair_state::dsp_test_or_clip_r)
{
return m_dsp_test_or_clip;
}
READ16_MEMBER(taitoair_state::dsp_test_and_clip_r)
{
return m_dsp_test_and_clip;
}
WRITE16_MEMBER(taitoair_state::dsp_muldiv_a_1_w)
{
m_dsp_muldiv_a_1 = data;
}
WRITE16_MEMBER(taitoair_state::dsp_muldiv_b_1_w)
{
m_dsp_muldiv_b_1 = data;
}
WRITE16_MEMBER(taitoair_state::dsp_muldiv_c_1_w)
{
m_dsp_muldiv_c_1 = data;
}
READ16_MEMBER(taitoair_state::dsp_muldiv_1_r)
{
return m_dsp_muldiv_a_1*m_dsp_muldiv_b_1/m_dsp_muldiv_c_1;
}
WRITE16_MEMBER(taitoair_state::dsp_muldiv_a_2_w)
{
m_dsp_muldiv_a_2 = data;
}
WRITE16_MEMBER(taitoair_state::dsp_muldiv_b_2_w)
{
m_dsp_muldiv_b_2 = data;
}
WRITE16_MEMBER(taitoair_state::dsp_muldiv_c_2_w)
{
m_dsp_muldiv_c_2 = data;
}
READ16_MEMBER(taitoair_state::dsp_muldiv_2_r)
{
return m_dsp_muldiv_a_2*m_dsp_muldiv_b_2/m_dsp_muldiv_c_2;
}
*/
static ADDRESS_MAP_START( DSP_map_program, AS_PROGRAM, 16, taitoair_state )
AM_RANGE(0x0000, 0x1fff) AM_ROM
@ -447,18 +509,23 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( DSP_map_data, AS_DATA, 16, taitoair_state )
AM_RANGE(0x2003, 0x2003) AM_READNOP //bit 0 DMA status flag or vblank
AM_RANGE(0x3000, 0x3002) AM_WRITE(dsp_flags_w)
AM_RANGE(0x3404, 0x3404) AM_WRITE(dsp_frustum_left_w)
AM_RANGE(0x3405, 0x3405) AM_WRITE(dsp_x_eyecoord_w)
AM_RANGE(0x3406, 0x3406) AM_WRITE(dsp_z_eyecoord_w)
AM_RANGE(0x3407, 0x3407) AM_READ(dsp_x_return_r)
AM_RANGE(0x3408, 0x3408) AM_WRITE(dsp_frustum_bottom_w)
AM_RANGE(0x3409, 0x3409) AM_WRITE(dsp_y_eyecoord_w)
AM_RANGE(0x340a, 0x340a) AM_WRITE(dsp_rasterize_w) /* Just a (lame) guess */
AM_RANGE(0x340b, 0x340b) AM_READ(dsp_y_return_r)
// AM_RANGE(0x3418, 0x341a) AM_WRITE(dsp_sqrt_w)
// AM_RANGE(0x341b, 0x341b) AM_WRITE(dsp_sqrt_r)
// AM_RANGE(0x341c, 0x341c) AM_READ(dsp_sqrt_flags1_r)
// AM_RANGE(0x341d, 0x341d) AM_READ(dsp_sqrt_flags2_r)
AM_RANGE(0x3404, 0x3404) AM_WRITE(dsp_muldiv_a_1_w)
AM_RANGE(0x3405, 0x3405) AM_WRITE(dsp_muldiv_b_1_w)
AM_RANGE(0x3406, 0x3406) AM_WRITE(dsp_muldiv_c_1_w)
AM_RANGE(0x3407, 0x3407) AM_READ(dsp_muldiv_1_r)
AM_RANGE(0x3408, 0x3408) AM_WRITE(dsp_muldiv_a_2_w)
AM_RANGE(0x3409, 0x3409) AM_WRITE(dsp_muldiv_b_2_w)
AM_RANGE(0x340a, 0x340a) AM_WRITE(dsp_muldiv_c_2_w)
AM_RANGE(0x340b, 0x340b) AM_READ(dsp_muldiv_2_r)
AM_RANGE(0x3418, 0x3418) AM_WRITE(dsp_test_x_w)
AM_RANGE(0x3419, 0x3419) AM_WRITE(dsp_test_y_w)
AM_RANGE(0x341a, 0x341a) AM_WRITE(dsp_test_z_w)
AM_RANGE(0x341b, 0x341b) AM_READWRITE(dsp_test_point_r, dsp_test_start_w)
AM_RANGE(0x341c, 0x341c) AM_READ(dsp_test_and_clip_r)
AM_RANGE(0x341d, 0x341d) AM_READ(dsp_test_or_clip_r)
AM_RANGE(0x4000, 0x7fff) AM_READWRITE(lineram_r, lineram_w)
AM_RANGE(0x8000, 0xffff) AM_READWRITE(dspram_r, dspram_w)
ADDRESS_MAP_END

View File

@ -76,6 +76,35 @@ public:
bool m_gradbank;
DECLARE_READ16_MEMBER(dsp_m_r);
DECLARE_WRITE16_MEMBER(dsp_m_w);
UINT16 m_dsp_test_object_type;
INT16 m_dsp_test_or_clip, m_dsp_test_and_clip;
INT16 m_dsp_test_x, m_dsp_test_y, m_dsp_test_z;
DECLARE_WRITE16_MEMBER(dsp_test_start_w);
DECLARE_WRITE16_MEMBER(dsp_test_x_w);
DECLARE_WRITE16_MEMBER(dsp_test_y_w);
DECLARE_WRITE16_MEMBER(dsp_test_z_w);
DECLARE_READ16_MEMBER(dsp_test_point_r);
DECLARE_READ16_MEMBER(dsp_test_or_clip_r);
DECLARE_READ16_MEMBER(dsp_test_and_clip_r);
INT16 m_dsp_muldiv_a_1, m_dsp_muldiv_b_1, m_dsp_muldiv_c_1;
DECLARE_WRITE16_MEMBER(dsp_muldiv_a_1_w);
DECLARE_WRITE16_MEMBER(dsp_muldiv_b_1_w);
DECLARE_WRITE16_MEMBER(dsp_muldiv_c_1_w);
DECLARE_READ16_MEMBER(dsp_muldiv_1_r);
INT16 m_dsp_muldiv_a_2, m_dsp_muldiv_b_2, m_dsp_muldiv_c_2;
DECLARE_WRITE16_MEMBER(dsp_muldiv_a_2_w);
DECLARE_WRITE16_MEMBER(dsp_muldiv_b_2_w);
DECLARE_WRITE16_MEMBER(dsp_muldiv_c_2_w);
DECLARE_READ16_MEMBER(dsp_muldiv_2_r);
//bitmap_ind16 *m_buffer3d;
DECLARE_WRITE16_MEMBER(system_control_w);
DECLARE_READ16_MEMBER(lineram_r);
@ -90,14 +119,7 @@ public:
DECLARE_READ16_MEMBER(stick2_input_r);
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
DECLARE_WRITE16_MEMBER(dsp_flags_w);
DECLARE_WRITE16_MEMBER(dsp_x_eyecoord_w);
DECLARE_WRITE16_MEMBER(dsp_y_eyecoord_w);
DECLARE_WRITE16_MEMBER(dsp_z_eyecoord_w);
DECLARE_WRITE16_MEMBER(dsp_frustum_left_w);
DECLARE_WRITE16_MEMBER(dsp_frustum_bottom_w);
DECLARE_WRITE16_MEMBER(dsp_rasterize_w);
DECLARE_READ16_MEMBER(dsp_x_return_r);
DECLARE_READ16_MEMBER(dsp_y_return_r);
virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
@ -106,8 +128,6 @@ public:
int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int start_offset );
void fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect, int color, INT32 x1, INT32 x2, INT32 sl1, INT32 sl2, INT32 y1, INT32 y2, INT32 *nx1, INT32 *nx2 );
void multVecMtx(const INT16* vec4, const float* m, float* result);
void airInfernoFrustum(const INT16 leftExtent, const INT16 bottomExtent, float* m);
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);
DECLARE_WRITE_LINE_MEMBER(irqhandler);

View File

@ -451,139 +451,6 @@ WRITE16_MEMBER(taitoair_state::dsp_flags_w)
}
}
WRITE16_MEMBER(taitoair_state::dsp_x_eyecoord_w)
{
m_eyecoordBuffer[0] = data;
}
WRITE16_MEMBER(taitoair_state::dsp_y_eyecoord_w)
{
m_eyecoordBuffer[1] = data;
}
WRITE16_MEMBER(taitoair_state::dsp_z_eyecoord_w)
{
m_eyecoordBuffer[2] = data;
}
WRITE16_MEMBER(taitoair_state::dsp_frustum_left_w)
{
/* Strange. It comes in as it it were the right side of the screen */
m_frustumLeft = -data;
}
WRITE16_MEMBER(taitoair_state::dsp_frustum_bottom_w)
{
m_frustumBottom = data;
}
void taitoair_state::multVecMtx(const INT16* vec4, const float* m, float* result)
{
#define M(row,col) m[col*4+row]
result[0] = vec4[0]*M(0,0) + vec4[1]*M(1,0) + vec4[2]*M(2,0) + vec4[3]*M(3,0);
result[1] = vec4[0]*M(0,1) + vec4[1]*M(1,1) + vec4[2]*M(2,1) + vec4[3]*M(3,1);
result[2] = vec4[0]*M(0,2) + vec4[1]*M(1,2) + vec4[2]*M(2,2) + vec4[3]*M(3,2);
float w = vec4[0]*M(0,3) + vec4[1]*M(1,3) + vec4[2]*M(2,3) + vec4[3]*M(3,3);
result[0] /= w;
result[1] /= w;
result[2] /= w;
#undef M
}
int taitoair_state::projectEyeCoordToScreen(float* projectionMatrix,const int Res,INT16* eyePoint3d,int type)
{
/* Return (-1, -1) if the eye point is behind camera */
int res = -10000;
if (eyePoint3d[2] <= 0.0 && eyePoint3d[0] <= 0.0)
return -10000;
if (eyePoint3d[2] <= 0.0 && eyePoint3d[0] >= 0.0)
return 10000;
/* Coordinate system flip */
eyePoint3d[0] *= -1;
/* Nothing fancy about this homogeneous worldspace coordinate */
eyePoint3d[3] = 1;
float deviceCoordinates[3];
multVecMtx(eyePoint3d, projectionMatrix, deviceCoordinates);
/* We're only interested if it projects within the device */
// if ( ( deviceCoordinates[type] >= -1.0) && ( deviceCoordinates[type] <= 1.0))
res = (int)( deviceCoordinates[type] * (Res-1) );
return res;
}
void taitoair_state::airInfernoFrustum(const INT16 leftExtent, const INT16 bottomExtent, float* m)
{
/* Hard-coded near and far clipping planes :( */
float nearZ = 1.0f;
float farZ = 10000.0f;
float left = 1.0f;
float right = -1.0f;
float bottom = (float)(-bottomExtent) / leftExtent;
float top = (float)(bottomExtent) / leftExtent;
float x = (2.0f*nearZ) / (right-left);
float y = (2.0f*nearZ) / (top-bottom);
float a = (right+left) / (right-left);
float b = (top+bottom) / (top-bottom);
float c = -(farZ+nearZ) / ( farZ-nearZ);
float d = -(2.0f*farZ*nearZ) / (farZ-nearZ);
#define M(row,col) m[col*4+row]
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
#undef M
}
WRITE16_MEMBER(taitoair_state::dsp_rasterize_w)
{
}
READ16_MEMBER(taitoair_state::dsp_x_return_r)
{
/* Construct a frustum from the system's most recently set left and bottom extents */
float m[16];
airInfernoFrustum(m_frustumLeft, m_frustumBottom, m);
int res;
res = projectEyeCoordToScreen(m,
32*16, /* x max screen size */
m_eyecoordBuffer,0);
// Extremely poor man's clipping :-P
if (res == -10000) return -32*8;
if (res == 10000) return 32*8-1;
if (res > 32*8-1) res = 32*8-1;
if (res < -32*8) res = -32*8;
return res;
}
READ16_MEMBER(taitoair_state::dsp_y_return_r)
{
/* Construct a frustum from the system's most recently set left and bottom extents */
float m[16];
airInfernoFrustum(m_frustumLeft, m_frustumBottom, m);
int res;
res = projectEyeCoordToScreen(m,
28*16, /* y max screen size */
m_eyecoordBuffer, 1);
// Extremely poor man's clipping :-P
if (res == -10000) return 28*7;
if (res == 10000) return 28*7;
if (res > 28*7) res = 28*7;
if (res < -28*7) res = -28*7;
return res;
}
void taitoair_state::video_start()
{
int width, height;