moved more model3 code into the driver class. nw.
This commit is contained in:
parent
f5586a0ca8
commit
36d52e3c9c
@ -1223,59 +1223,58 @@ MACHINE_START_MEMBER(model3_state,model3_21)
|
||||
m_sound_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(model3_state::model3_sound_timer_tick),this));
|
||||
}
|
||||
|
||||
static void model3_init(running_machine &machine, int step)
|
||||
void model3_state::model3_init(int step)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
state->m_step = step;
|
||||
m_step = step;
|
||||
|
||||
state->m_sound_irq_enable = 0;
|
||||
state->m_sound_timer->adjust(attotime::never);
|
||||
m_sound_irq_enable = 0;
|
||||
m_sound_timer->adjust(attotime::never);
|
||||
|
||||
state->membank("bank1")->set_base(state->memregion( "user1" )->base() + 0x800000 ); /* banked CROM */
|
||||
membank("bank1")->set_base(memregion( "user1" )->base() + 0x800000 ); /* banked CROM */
|
||||
|
||||
state->membank("bank4")->set_base(state->memregion("samples")->base() + 0x200000);
|
||||
state->membank("bank5")->set_base(state->memregion("samples")->base() + 0x600000);
|
||||
membank("bank4")->set_base(memregion("samples")->base() + 0x200000);
|
||||
membank("bank5")->set_base(memregion("samples")->base() + 0x600000);
|
||||
|
||||
// copy the 68k vector table into RAM
|
||||
memcpy(state->m_soundram, state->memregion("audiocpu")->base()+0x80000, 16);
|
||||
machine.device("audiocpu")->reset();
|
||||
memcpy(m_soundram, memregion("audiocpu")->base()+0x80000, 16);
|
||||
machine().device("audiocpu")->reset();
|
||||
|
||||
model3_machine_init(machine, step); // step 1.5
|
||||
model3_tap_reset(machine);
|
||||
m_m3_step = step; // step = BCD hardware rev. 0x10 for 1.0, 0x15 for 1.5, 0x20 for 2.0, etc.
|
||||
tap_reset();
|
||||
|
||||
if(step < 0x20) {
|
||||
if( core_stricmp(machine.system().name, "vs215") == 0 ||
|
||||
core_stricmp(machine.system().name, "vs29815") == 0 ||
|
||||
core_stricmp(machine.system().name, "bass") == 0 )
|
||||
if (step < 0x20) {
|
||||
if( core_stricmp(machine().system().name, "vs215") == 0 ||
|
||||
core_stricmp(machine().system().name, "vs29815") == 0 ||
|
||||
core_stricmp(machine().system().name, "bass") == 0 )
|
||||
{
|
||||
mpc106_init(machine);
|
||||
mpc106_init(machine());
|
||||
}
|
||||
else
|
||||
{
|
||||
mpc105_init(machine);
|
||||
mpc105_init(machine());
|
||||
}
|
||||
state->m_real3d_device_id = 0x16c311db; /* PCI Vendor ID (11db = SEGA), Device ID (16c3 = 315-5827) */
|
||||
m_real3d_device_id = 0x16c311db; /* PCI Vendor ID (11db = SEGA), Device ID (16c3 = 315-5827) */
|
||||
}
|
||||
else {
|
||||
mpc106_init(machine);
|
||||
mpc106_init(machine());
|
||||
// some step 2+ games need the older PCI ID (obvious symptom:
|
||||
// vbl is enabled briefly then disabled so the game hangs)
|
||||
if (core_stricmp(machine.system().name, "magtruck") == 0 ||
|
||||
core_stricmp(machine.system().name, "von254g") == 0)
|
||||
if (core_stricmp(machine().system().name, "magtruck") == 0 ||
|
||||
core_stricmp(machine().system().name, "von254g") == 0)
|
||||
{
|
||||
state->m_real3d_device_id = 0x16c311db; /* PCI Vendor ID (11db = SEGA), Device ID (16c3 = 315-5827) */
|
||||
m_real3d_device_id = 0x16c311db; /* PCI Vendor ID (11db = SEGA), Device ID (16c3 = 315-5827) */
|
||||
}
|
||||
else
|
||||
{
|
||||
state->m_real3d_device_id = 0x178611db; /* PCI Vendor ID (11db = SEGA), Device ID (1786 = 315-6022) */
|
||||
m_real3d_device_id = 0x178611db; /* PCI Vendor ID (11db = SEGA), Device ID (1786 = 315-6022) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_10){ model3_init(machine(), 0x10); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_15){ model3_init(machine(), 0x15); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_20){ model3_init(machine(), 0x20); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_21){ model3_init(machine(), 0x21); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_10){ model3_init(0x10); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_15){ model3_init(0x15); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_20){ model3_init(0x20); }
|
||||
MACHINE_RESET_MEMBER(model3_state,model3_21){ model3_init(0x21); }
|
||||
|
||||
|
||||
READ64_MEMBER(model3_state::model3_ctrl_r)
|
||||
@ -1466,7 +1465,7 @@ READ64_MEMBER(model3_state::model3_sys_r)
|
||||
case 0x10/8:
|
||||
if (ACCESSING_BITS_56_63)
|
||||
{
|
||||
UINT64 res = model3_tap_read(machine());
|
||||
UINT64 res = tap_read();
|
||||
|
||||
return res<<61;
|
||||
}
|
||||
@ -1545,8 +1544,7 @@ WRITE64_MEMBER(model3_state::model3_sys_w)
|
||||
if (ACCESSING_BITS_24_31)
|
||||
{
|
||||
data >>= 24;
|
||||
model3_tap_write(machine(),
|
||||
(data >> 6) & 1,// TCK
|
||||
tap_write((data >> 6) & 1,// TCK
|
||||
(data >> 2) & 1,// TMS
|
||||
(data >> 5) & 1,// TDI
|
||||
(data >> 7) & 1 // TRST
|
||||
|
@ -31,6 +31,17 @@ public:
|
||||
m_dsbz80(*this, DSBZ80_TAG),
|
||||
m_soundram(*this, "soundram") { }
|
||||
|
||||
struct TRIANGLE
|
||||
{
|
||||
poly_vertex v[3];
|
||||
UINT8 texture_x, texture_y;
|
||||
UINT8 texture_width, texture_height;
|
||||
UINT8 transparency;
|
||||
UINT8 texture_format, param;
|
||||
int intensity;
|
||||
UINT32 color;
|
||||
};
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
optional_device<lsi53c810_device> m_lsi53c810;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
@ -219,18 +230,45 @@ public:
|
||||
LSI53C810_IRQ_CB(scsi_irq_callback);
|
||||
void update_irq_state();
|
||||
void set_irq_line(UINT8 bit, int line);
|
||||
void model3_init(int step);
|
||||
// video
|
||||
void draw_tile_4bit(bitmap_ind16 &bitmap, int tx, int ty, int tilenum);
|
||||
void draw_tile_8bit(bitmap_ind16 &bitmap, int tx, int ty, int tilenum);
|
||||
void draw_layer(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int bitdepth);
|
||||
void invalidate_texture(int page, int texx, int texy, int texwidth, int texheight);
|
||||
cached_texture *get_texture(int page, int texx, int texy, int texwidth, int texheight, int format);
|
||||
inline void write_texture16(int xpos, int ypos, int width, int height, int page, UINT16 *data);
|
||||
void real3d_upload_texture(UINT32 header, UINT32 *data);
|
||||
void init_matrix_stack();
|
||||
void get_top_matrix(MATRIX *out);
|
||||
void push_matrix_stack();
|
||||
void pop_matrix_stack();
|
||||
void multiply_matrix_stack(MATRIX matrix);
|
||||
void translate_matrix_stack(float x, float y, float z);
|
||||
void render_one(TRIANGLE *tri);
|
||||
void draw_model(UINT32 addr);
|
||||
UINT32 *get_memory_pointer(UINT32 address);
|
||||
void load_matrix(int matrix_num, MATRIX *out);
|
||||
void traverse_list4(int lod_num, UINT32 address);
|
||||
void traverse_list(UINT32 address);
|
||||
inline void process_link(UINT32 address, UINT32 link);
|
||||
void draw_block(UINT32 address);
|
||||
void draw_viewport(int pri, UINT32 address);
|
||||
void real3d_traverse_display_list();
|
||||
#ifdef UNUSED_FUNCTION
|
||||
inline void write_texture8(int xpos, int ypos, int width, int height, int page, UINT16 *data);
|
||||
void draw_texture_sheet(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void copy_screen(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
#endif
|
||||
void real3d_display_list_end();
|
||||
void real3d_display_list1_dma(UINT32 src, UINT32 dst, int length, int byteswap);
|
||||
void real3d_display_list2_dma(UINT32 src, UINT32 dst, int length, int byteswap);
|
||||
void real3d_vrom_texture_dma(UINT32 src, UINT32 dst, int length, int byteswap);
|
||||
void real3d_texture_fifo_dma(UINT32 src, int length, int byteswap);
|
||||
void real3d_polygon_ram_dma(UINT32 src, UINT32 dst, int length, int byteswap);
|
||||
// machine
|
||||
void insert_id(UINT32 id, INT32 start_bit);
|
||||
int tap_read();
|
||||
void tap_write(int tck, int tms, int tdi, int trst);
|
||||
void tap_reset();
|
||||
};
|
||||
|
||||
/*----------- defined in machine/model3.c -----------*/
|
||||
|
||||
void model3_machine_init(running_machine &machine, int step);
|
||||
int model3_tap_read(running_machine &machine);
|
||||
void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int trst);
|
||||
void model3_tap_reset(running_machine &machine);
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* 167 of the 3D-RAM manual.
|
||||
*/
|
||||
|
||||
#define NEXT(new_state) fsm[state->m_tap_state][new_state]
|
||||
#define NEXT(new_state) fsm[m_tap_state][new_state]
|
||||
|
||||
static const INT32 fsm[][2] = {
|
||||
{ 1, 0 }, // 0 Test-Logic/Reset
|
||||
@ -64,12 +64,10 @@ static void insert_bit(UINT8 *buf, INT32 bit_num, INT32 bit)
|
||||
* Inserts a 32-bit ID code into the ID bit field.
|
||||
*/
|
||||
|
||||
static void insert_id(model3_state *state, UINT32 id, INT32 start_bit)
|
||||
void model3_state::insert_id(UINT32 id, INT32 start_bit)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 31; i >= 0; i--)
|
||||
insert_bit(state->m_id_data, start_bit++, (id >> i) & 1);
|
||||
for (int i = 31; i >= 0; i--)
|
||||
insert_bit(m_id_data, start_bit++, (id >> i) & 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -122,10 +120,9 @@ static int shift(UINT8 *data, INT32 num_bits)
|
||||
* TDO.
|
||||
*/
|
||||
|
||||
int model3_tap_read(running_machine &machine)
|
||||
int model3_state::tap_read()
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
return state->m_tdo;
|
||||
return m_tdo;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -141,15 +138,14 @@ int model3_tap_read(running_machine &machine)
|
||||
* trst = Reset.
|
||||
*/
|
||||
|
||||
void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int trst)
|
||||
void model3_state::tap_write(int tck, int tms, int tdi, int trst)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
if (!tck)
|
||||
return;
|
||||
|
||||
state->m_tap_state = NEXT(tms);
|
||||
m_tap_state = NEXT(tms);
|
||||
|
||||
switch (state->m_tap_state)
|
||||
switch (m_tap_state)
|
||||
{
|
||||
case 3: // Capture-DR
|
||||
|
||||
@ -175,39 +171,39 @@ void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int t
|
||||
* data on TAP reset and when the instruction is issued.
|
||||
*/
|
||||
|
||||
if (state->m_m3_step == 0x10)
|
||||
if (m_m3_step == 0x10)
|
||||
{
|
||||
insert_id(state, 0x116C7057, 1 + 0 * 32);
|
||||
insert_id(state, 0x216C3057, 1 + 1 * 32);
|
||||
insert_id(state, 0x116C4057, 1 + 2 * 32);
|
||||
insert_id(state, 0x216C5057, 1 + 3 * 32);
|
||||
insert_id(state, 0x116C6057, 1 + 4 * 32 + 1);
|
||||
insert_id(state, 0x116C6057, 1 + 5 * 32 + 1);
|
||||
insert_id(0x116C7057, 1 + 0 * 32);
|
||||
insert_id(0x216C3057, 1 + 1 * 32);
|
||||
insert_id(0x116C4057, 1 + 2 * 32);
|
||||
insert_id(0x216C5057, 1 + 3 * 32);
|
||||
insert_id(0x116C6057, 1 + 4 * 32 + 1);
|
||||
insert_id(0x116C6057, 1 + 5 * 32 + 1);
|
||||
}
|
||||
else if (state->m_m3_step == 0x15)
|
||||
else if (m_m3_step == 0x15)
|
||||
{
|
||||
insert_id(state, 0x316C7057, 1 + 0 * 32);
|
||||
insert_id(state, 0x316C3057, 1 + 1 * 32);
|
||||
insert_id(state, 0x216C4057, 1 + 2 * 32); // Lost World may to use 0x016C4057
|
||||
insert_id(state, 0x316C5057, 1 + 3 * 32);
|
||||
insert_id(state, 0x216C6057, 1 + 4 * 32 + 1);
|
||||
insert_id(state, 0x216C6057, 1 + 5 * 32 + 1);
|
||||
insert_id(0x316C7057, 1 + 0 * 32);
|
||||
insert_id(0x316C3057, 1 + 1 * 32);
|
||||
insert_id(0x216C4057, 1 + 2 * 32); // Lost World may to use 0x016C4057
|
||||
insert_id(0x316C5057, 1 + 3 * 32);
|
||||
insert_id(0x216C6057, 1 + 4 * 32 + 1);
|
||||
insert_id(0x216C6057, 1 + 5 * 32 + 1);
|
||||
}
|
||||
else if (state->m_m3_step >= 0x20)
|
||||
else if (m_m3_step >= 0x20)
|
||||
{
|
||||
insert_id(state, 0x416C7057, 1 + 0 * 32);
|
||||
insert_id(state, 0x416C3057, 1 + 1 * 32);
|
||||
insert_id(state, 0x316C4057, 1 + 2 * 32);
|
||||
insert_id(state, 0x416C5057, 1 + 3 * 32);
|
||||
insert_id(state, 0x316C6057, 1 + 4 * 32 + 1);
|
||||
insert_id(state, 0x316C6057, 1 + 5 * 32 + 1);
|
||||
insert_id(0x416C7057, 1 + 0 * 32);
|
||||
insert_id(0x416C3057, 1 + 1 * 32);
|
||||
insert_id(0x316C4057, 1 + 2 * 32);
|
||||
insert_id(0x416C5057, 1 + 3 * 32);
|
||||
insert_id(0x316C6057, 1 + 4 * 32 + 1);
|
||||
insert_id(0x316C6057, 1 + 5 * 32 + 1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4: // Shift-DR
|
||||
|
||||
state->m_tdo = shift(state->m_id_data, state->m_id_size);
|
||||
m_tdo = shift(m_id_data, m_id_size);
|
||||
break;
|
||||
|
||||
case 10: // Capture-IR
|
||||
@ -216,7 +212,7 @@ void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int t
|
||||
* Load lower 2 bits with 01 as per IEEE 1149.1-1990
|
||||
*/
|
||||
|
||||
state->m_ir = 1;
|
||||
m_ir = 1;
|
||||
break;
|
||||
|
||||
case 11: // Shift-IR
|
||||
@ -225,9 +221,9 @@ void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int t
|
||||
* Shift IR towards output and load in new data from TDI
|
||||
*/
|
||||
|
||||
state->m_tdo = state->m_ir & 1; // shift LSB to output
|
||||
state->m_ir >>= 1;
|
||||
state->m_ir |= ((UINT64) tdi << 45);
|
||||
m_tdo = m_ir & 1; // shift LSB to output
|
||||
m_ir >>= 1;
|
||||
m_ir |= ((UINT64) tdi << 45);
|
||||
break;
|
||||
|
||||
case 15: // Update-IR
|
||||
@ -237,7 +233,7 @@ void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int t
|
||||
* TCK)
|
||||
*/
|
||||
|
||||
state->m_ir &= U64(0x3fffffffffff);
|
||||
m_ir &= U64(0x3fffffffffff);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -252,25 +248,10 @@ void model3_tap_write(running_machine &machine, int tck, int tms, int tdi, int t
|
||||
* Resets the TAP (simulating a power up or SCAN_RST signal.)
|
||||
*/
|
||||
|
||||
void model3_tap_reset(running_machine &machine)
|
||||
void model3_state::tap_reset()
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
state->m_id_size = 197; // 197 bits
|
||||
|
||||
state->m_tap_state = 0; // test-logic/reset
|
||||
}
|
||||
|
||||
/*
|
||||
* void model3_machine_init(int step)
|
||||
*
|
||||
* step = BCD hardware rev. 0x10 for 1.0, 0x15 for 1.5, 0x20 for 2.0, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
void model3_machine_init(running_machine &machine, int step)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
state->m_m3_step = step;
|
||||
m_id_size = 197; // 197 bits
|
||||
m_tap_state = 0; // test-logic/reset
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -9,20 +9,6 @@
|
||||
#define pv p[2]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct TRIANGLE
|
||||
{
|
||||
poly_vertex v[3];
|
||||
UINT8 texture_x, texture_y;
|
||||
UINT8 texture_width, texture_height;
|
||||
UINT8 transparency;
|
||||
UINT8 texture_format, param;
|
||||
int intensity;
|
||||
UINT32 color;
|
||||
};
|
||||
|
||||
struct cached_texture
|
||||
{
|
||||
cached_texture *next;
|
||||
@ -52,39 +38,8 @@ struct poly_extra_data
|
||||
#define MAX_TRIANGLES 131072
|
||||
|
||||
|
||||
/* forward declarations */
|
||||
static void real3d_traverse_display_list(running_machine &machine);
|
||||
static void draw_model(running_machine &machine, UINT32 addr);
|
||||
static void init_matrix_stack(running_machine &machine);
|
||||
static void get_top_matrix(model3_state *state, MATRIX *out);
|
||||
static void push_matrix_stack(model3_state *state);
|
||||
static void pop_matrix_stack(model3_state *state);
|
||||
static void multiply_matrix_stack(model3_state *state, MATRIX matrix);
|
||||
static void translate_matrix_stack(model3_state *state, float x, float y, float z);
|
||||
static void traverse_list(running_machine &machine, UINT32 address);
|
||||
static void draw_block(running_machine &machine, UINT32 address);
|
||||
static void draw_viewport(running_machine &machine, int pri, UINT32 address);
|
||||
static void invalidate_texture(running_machine &machine, int page, int texx, int texy, int texwidth, int texheight);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* matrix stack */
|
||||
#define MATRIX_STACK_SIZE 256
|
||||
|
||||
@ -107,8 +62,8 @@ static const int num_bits[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
|
||||
|
||||
void model3_state::model3_exit()
|
||||
{
|
||||
invalidate_texture(machine(), 0, 0, 0, 6, 5);
|
||||
invalidate_texture(machine(), 1, 0, 0, 6, 5);
|
||||
invalidate_texture(0, 0, 0, 6, 5);
|
||||
invalidate_texture(1, 0, 0, 6, 5);
|
||||
poly_free(m_poly);
|
||||
}
|
||||
|
||||
@ -148,14 +103,13 @@ void model3_state::video_start()
|
||||
m_viewport_region_width = 496;
|
||||
m_viewport_region_height = 384;
|
||||
|
||||
init_matrix_stack(machine());
|
||||
init_matrix_stack();
|
||||
}
|
||||
|
||||
static void draw_tile_4bit(running_machine &machine, bitmap_ind16 &bitmap, int tx, int ty, int tilenum)
|
||||
void model3_state::draw_tile_4bit(bitmap_ind16 &bitmap, int tx, int ty, int tilenum)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int x, y;
|
||||
UINT8 *tile_base = (UINT8*)state->m_m3_char_ram;
|
||||
UINT8 *tile_base = (UINT8*)m_m3_char_ram;
|
||||
UINT8 *tile;
|
||||
|
||||
int data = (BYTE_REVERSE16(tilenum));
|
||||
@ -172,8 +126,8 @@ static void draw_tile_4bit(running_machine &machine, bitmap_ind16 &bitmap, int t
|
||||
UINT16 pix0, pix1;
|
||||
tile0 = *tile >> 4;
|
||||
tile1 = *tile & 0xf;
|
||||
pix0 = state->m_pal_lookup[c + tile0];
|
||||
pix1 = state->m_pal_lookup[c + tile1];
|
||||
pix0 = m_pal_lookup[c + tile0];
|
||||
pix1 = m_pal_lookup[c + tile1];
|
||||
if((pix0 & 0x8000) == 0)
|
||||
{
|
||||
d[x+0] = pix0;
|
||||
@ -187,11 +141,10 @@ static void draw_tile_4bit(running_machine &machine, bitmap_ind16 &bitmap, int t
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_tile_8bit(running_machine &machine, bitmap_ind16 &bitmap, int tx, int ty, int tilenum)
|
||||
void model3_state::draw_tile_8bit(bitmap_ind16 &bitmap, int tx, int ty, int tilenum)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int x, y;
|
||||
UINT8 *tile_base = (UINT8*)state->m_m3_char_ram;
|
||||
UINT8 *tile_base = (UINT8*)m_m3_char_ram;
|
||||
UINT8 *tile;
|
||||
|
||||
int data = (BYTE_REVERSE16(tilenum));
|
||||
@ -208,7 +161,7 @@ static void draw_tile_8bit(running_machine &machine, bitmap_ind16 &bitmap, int t
|
||||
UINT8 tile0;
|
||||
UINT16 pix;
|
||||
tile0 = tile[xx^4];
|
||||
pix = state->m_pal_lookup[c + tile0];
|
||||
pix = m_pal_lookup[c + tile0];
|
||||
if((pix & 0x8000) == 0)
|
||||
{
|
||||
d[x] = pix;
|
||||
@ -219,16 +172,15 @@ static void draw_tile_8bit(running_machine &machine, bitmap_ind16 &bitmap, int t
|
||||
}
|
||||
}
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static void draw_texture_sheet(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
void model3_state::draw_texture_sheet(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int x,y;
|
||||
for(y = cliprect.min_y; y <= cliprect.max_y; y++)
|
||||
{
|
||||
UINT16 *d = &bitmap.pix16(y);
|
||||
int index = (y*2)*2048;
|
||||
for(x = cliprect.min_x; x <= cliprect.max_x; x++) {
|
||||
UINT16 pix = state->m_texture_ram[0][index];
|
||||
UINT16 pix = m_texture_ram[0][index];
|
||||
index+=4;
|
||||
if(pix != 0) {
|
||||
d[x] = pix;
|
||||
@ -238,52 +190,51 @@ static void draw_texture_sheet(running_machine &machine, bitmap_ind16 &bitmap, c
|
||||
}
|
||||
#endif
|
||||
|
||||
static void draw_layer(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int bitdepth)
|
||||
void model3_state::draw_layer(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int bitdepth)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int x, y;
|
||||
int tile_index = 0;
|
||||
UINT16 *tiles = (UINT16*)&state->m_m3_tile_ram[layer * 0x400];
|
||||
UINT16 *tiles = (UINT16*)&m_m3_tile_ram[layer * 0x400];
|
||||
|
||||
//logerror("Layer %d: X: %d, Y: %d\n", layer, x1, y1);
|
||||
|
||||
if(layer > 1) {
|
||||
int modr = (state->m_layer_modulate2 >> 8) & 0xff;
|
||||
int modg = (state->m_layer_modulate2 >> 16) & 0xff;
|
||||
int modb = (state->m_layer_modulate2 >> 24) & 0xff;
|
||||
int modr = (m_layer_modulate2 >> 8) & 0xff;
|
||||
int modg = (m_layer_modulate2 >> 16) & 0xff;
|
||||
int modb = (m_layer_modulate2 >> 24) & 0xff;
|
||||
if(modr & 0x80) {
|
||||
state->m_layer_modulate_r = -(0x7f - (modr & 0x7f)) << 10;
|
||||
m_layer_modulate_r = -(0x7f - (modr & 0x7f)) << 10;
|
||||
} else {
|
||||
state->m_layer_modulate_r = (modr & 0x7f) << 10;
|
||||
m_layer_modulate_r = (modr & 0x7f) << 10;
|
||||
}
|
||||
if(modg & 0x80) {
|
||||
state->m_layer_modulate_g = -(0x7f - (modr & 0x7f)) << 5;
|
||||
m_layer_modulate_g = -(0x7f - (modr & 0x7f)) << 5;
|
||||
} else {
|
||||
state->m_layer_modulate_g = (modr & 0x7f) << 5;
|
||||
m_layer_modulate_g = (modr & 0x7f) << 5;
|
||||
}
|
||||
if(modb & 0x80) {
|
||||
state->m_layer_modulate_b = -(0x7f - (modr & 0x7f));
|
||||
m_layer_modulate_b = -(0x7f - (modr & 0x7f));
|
||||
} else {
|
||||
state->m_layer_modulate_b = (modr & 0x7f);
|
||||
m_layer_modulate_b = (modr & 0x7f);
|
||||
}
|
||||
} else {
|
||||
int modr = (state->m_layer_modulate1 >> 8) & 0xff;
|
||||
int modg = (state->m_layer_modulate1 >> 16) & 0xff;
|
||||
int modb = (state->m_layer_modulate1 >> 24) & 0xff;
|
||||
int modr = (m_layer_modulate1 >> 8) & 0xff;
|
||||
int modg = (m_layer_modulate1 >> 16) & 0xff;
|
||||
int modb = (m_layer_modulate1 >> 24) & 0xff;
|
||||
if(modr & 0x80) {
|
||||
state->m_layer_modulate_r = -(0x7f - (modr & 0x7f)) << 10;
|
||||
m_layer_modulate_r = -(0x7f - (modr & 0x7f)) << 10;
|
||||
} else {
|
||||
state->m_layer_modulate_r = (modr & 0x7f) << 10;
|
||||
m_layer_modulate_r = (modr & 0x7f) << 10;
|
||||
}
|
||||
if(modg & 0x80) {
|
||||
state->m_layer_modulate_g = -(0x7f - (modr & 0x7f)) << 5;
|
||||
m_layer_modulate_g = -(0x7f - (modr & 0x7f)) << 5;
|
||||
} else {
|
||||
state->m_layer_modulate_g = (modr & 0x7f) << 5;
|
||||
m_layer_modulate_g = (modr & 0x7f) << 5;
|
||||
}
|
||||
if(modb & 0x80) {
|
||||
state->m_layer_modulate_b = -(0x7f - (modr & 0x7f));
|
||||
m_layer_modulate_b = -(0x7f - (modr & 0x7f));
|
||||
} else {
|
||||
state->m_layer_modulate_b = (modr & 0x7f);
|
||||
m_layer_modulate_b = (modr & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +245,7 @@ static void draw_layer(running_machine &machine, bitmap_ind16 &bitmap, const rec
|
||||
tile_index = ((y/8) * 64);
|
||||
for (x = cliprect.min_x; x <= cliprect.max_x; x+=8) {
|
||||
UINT16 tile = tiles[tile_index ^ 0x2];
|
||||
draw_tile_4bit(machine, bitmap, x, y, tile);
|
||||
draw_tile_4bit(bitmap, x, y, tile);
|
||||
++tile_index;
|
||||
}
|
||||
}
|
||||
@ -306,7 +257,7 @@ static void draw_layer(running_machine &machine, bitmap_ind16 &bitmap, const rec
|
||||
tile_index = ((y/8) * 64);
|
||||
for (x = cliprect.min_x; x <= cliprect.max_x; x+=8) {
|
||||
UINT16 tile = tiles[tile_index ^ 0x2];
|
||||
draw_tile_8bit(machine, bitmap, x, y, tile);
|
||||
draw_tile_8bit(bitmap, x, y, tile);
|
||||
++tile_index;
|
||||
}
|
||||
}
|
||||
@ -314,13 +265,12 @@ static void draw_layer(running_machine &machine, bitmap_ind16 &bitmap, const rec
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static void copy_screen(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
static void copy_screen(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int x,y;
|
||||
for(y=cliprect.min_y; y <= cliprect.max_y; y++) {
|
||||
UINT16 *d = &bitmap.pix16(y);
|
||||
UINT16 *s = &state->m_bitmap3d.pix16(y);
|
||||
UINT16 *s = &m_bitmap3d.pix16(y);
|
||||
for(x=cliprect.min_x; x <= cliprect.max_x; x++) {
|
||||
UINT16 pix = s[x];
|
||||
if(!(pix & 0x8000)) {
|
||||
@ -374,10 +324,10 @@ UINT32 model3_state::screen_update_model3(screen_device &screen, bitmap_ind16 &b
|
||||
bitmap.fill(0, cliprect);
|
||||
|
||||
if (!(m_debug_layer_disable & 0x8))
|
||||
draw_layer(machine(), bitmap, cliprect, 3, (m_layer_enable >> 3) & 0x1);
|
||||
draw_layer(bitmap, cliprect, 3, (m_layer_enable >> 3) & 0x1);
|
||||
|
||||
if (!(m_debug_layer_disable & 0x4))
|
||||
draw_layer(machine(), bitmap, cliprect, 2, (m_layer_enable >> 2) & 0x1);
|
||||
draw_layer(bitmap, cliprect, 2, (m_layer_enable >> 2) & 0x1);
|
||||
|
||||
if( !(m_debug_layer_disable & 0x10) )
|
||||
{
|
||||
@ -385,17 +335,17 @@ UINT32 model3_state::screen_update_model3(screen_device &screen, bitmap_ind16 &b
|
||||
if(m_real3d_display_list) {
|
||||
m_zbuffer.fill(0, cliprect);
|
||||
m_bitmap3d.fill(0x8000, cliprect);
|
||||
real3d_traverse_display_list(machine());
|
||||
real3d_traverse_display_list();
|
||||
}
|
||||
#endif
|
||||
copybitmap_trans(bitmap, m_bitmap3d, 0, 0, 0, 0, cliprect, 0x8000);
|
||||
}
|
||||
|
||||
if (!(m_debug_layer_disable & 0x2))
|
||||
draw_layer(machine(), bitmap, cliprect, 1, (m_layer_enable >> 1) & 0x1);
|
||||
draw_layer(bitmap, cliprect, 1, (m_layer_enable >> 1) & 0x1);
|
||||
|
||||
if (!(m_debug_layer_disable & 0x1))
|
||||
draw_layer(machine(), bitmap, cliprect, 0, (m_layer_enable >> 0) & 0x1);
|
||||
draw_layer(bitmap, cliprect, 0, (m_layer_enable >> 0) & 0x1);
|
||||
|
||||
//copy_screen(bitmap, cliprect);
|
||||
|
||||
@ -495,51 +445,48 @@ READ64_MEMBER(model3_state::model3_palette_r)
|
||||
1024 pixels / 32 pixel resolution vertically
|
||||
2048 pixels / 32 pixel resolution horizontally
|
||||
*/
|
||||
static void invalidate_texture(running_machine &machine, int page, int texx, int texy, int texwidth, int texheight)
|
||||
void model3_state::invalidate_texture(int page, int texx, int texy, int texwidth, int texheight)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int wtiles = 1 << texwidth;
|
||||
int htiles = 1 << texheight;
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < htiles; y++)
|
||||
for (x = 0; x < wtiles; x++)
|
||||
while (state->m_texcache[page][texy + y][texx + x] != NULL)
|
||||
for (int y = 0; y < htiles; y++)
|
||||
for (int x = 0; x < wtiles; x++)
|
||||
while (m_texcache[page][texy + y][texx + x] != NULL)
|
||||
{
|
||||
cached_texture *freeme = state->m_texcache[page][texy + y][texx + x];
|
||||
state->m_texcache[page][texy + y][texx + x] = freeme->next;
|
||||
auto_free(machine, freeme);
|
||||
cached_texture *freeme = m_texcache[page][texy + y][texx + x];
|
||||
m_texcache[page][texy + y][texx + x] = freeme->next;
|
||||
auto_free(machine(), freeme);
|
||||
}
|
||||
}
|
||||
|
||||
static cached_texture *get_texture(running_machine &machine, int page, int texx, int texy, int texwidth, int texheight, int format)
|
||||
cached_texture *model3_state::get_texture(int page, int texx, int texy, int texwidth, int texheight, int format)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
cached_texture *tex = state->m_texcache[page][texy][texx];
|
||||
cached_texture *tex = m_texcache[page][texy][texx];
|
||||
int pixheight = 32 << texheight;
|
||||
int pixwidth = 32 << texwidth;
|
||||
UINT32 alpha = ~0;
|
||||
int x, y;
|
||||
|
||||
/* if we have one already, validate it */
|
||||
for (tex = state->m_texcache[page][texy][texx]; tex != NULL; tex = tex->next)
|
||||
for (tex = m_texcache[page][texy][texx]; tex != NULL; tex = tex->next)
|
||||
if (tex->width == texwidth && tex->height == texheight && tex->format == format)
|
||||
return tex;
|
||||
|
||||
/* create a new texture */
|
||||
tex = (cached_texture *)auto_alloc_array(machine, UINT8, sizeof(cached_texture) + (2 * pixwidth * 2 * pixheight) * sizeof(rgb_t));
|
||||
tex = (cached_texture *)auto_alloc_array(machine(), UINT8, sizeof(cached_texture) + (2 * pixwidth * 2 * pixheight) * sizeof(rgb_t));
|
||||
tex->width = texwidth;
|
||||
tex->height = texheight;
|
||||
tex->format = format;
|
||||
|
||||
/* set the new texture */
|
||||
tex->next = state->m_texcache[page][texy][texx];
|
||||
state->m_texcache[page][texy][texx] = tex;
|
||||
tex->next = m_texcache[page][texy][texx];
|
||||
m_texcache[page][texy][texx] = tex;
|
||||
|
||||
/* decode it */
|
||||
for (y = 0; y < pixheight; y++)
|
||||
{
|
||||
const UINT16 *texsrc = &state->m_texture_ram[page][(texy * 32 + y) * 2048 + texx * 32];
|
||||
const UINT16 *texsrc = &m_texture_ram[page][(texy * 32 + y) * 2048 + texx * 32];
|
||||
rgb_t *dest = tex->data + 2 * pixwidth * y;
|
||||
|
||||
switch (format)
|
||||
@ -660,7 +607,7 @@ static const UINT8 texture_decode[64] =
|
||||
50, 51, 54, 55, 58, 59, 62, 63
|
||||
};
|
||||
|
||||
INLINE void write_texture16(model3_state *state, int xpos, int ypos, int width, int height, int page, UINT16 *data)
|
||||
inline void model3_state::write_texture16(int xpos, int ypos, int width, int height, int page, UINT16 *data)
|
||||
{
|
||||
int x,y,i,j;
|
||||
|
||||
@ -668,7 +615,7 @@ INLINE void write_texture16(model3_state *state, int xpos, int ypos, int width,
|
||||
{
|
||||
for(x=xpos; x < xpos+width; x+=8)
|
||||
{
|
||||
UINT16 *texture = &state->m_texture_ram[page][y*2048+x];
|
||||
UINT16 *texture = &m_texture_ram[page][y*2048+x];
|
||||
int b = 0;
|
||||
for(j=y; j < y+8; j++) {
|
||||
for(i=x; i < x+8; i++) {
|
||||
@ -683,7 +630,7 @@ INLINE void write_texture16(model3_state *state, int xpos, int ypos, int width,
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
INLINE void write_texture8(model3_state *state, int xpos, int ypos, int width, int height, int page, UINT16 *data)
|
||||
inline void model3_state::write_texture8(int xpos, int ypos, int width, int height, int page, UINT16 *data)
|
||||
{
|
||||
int x,y,i,j;
|
||||
UINT16 color = 0x7c00;
|
||||
@ -692,7 +639,7 @@ INLINE void write_texture8(model3_state *state, int xpos, int ypos, int width, i
|
||||
{
|
||||
for(x=xpos; x < xpos+width; x+=8)
|
||||
{
|
||||
UINT16 *texture = &state->m_texture_ram[page][y*2048+x];
|
||||
UINT16 *texture = &m_texture_ram[page][y*2048+x];
|
||||
for(j=y; j < y+4; j++) {
|
||||
for(i=x; i < x+8; i++) {
|
||||
*texture = color;
|
||||
@ -705,9 +652,8 @@ INLINE void write_texture8(model3_state *state, int xpos, int ypos, int width, i
|
||||
}
|
||||
#endif
|
||||
|
||||
static void real3d_upload_texture(running_machine &machine, UINT32 header, UINT32 *data)
|
||||
void model3_state::real3d_upload_texture(UINT32 header, UINT32 *data)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int width = 32 << ((header >> 14) & 0x7);
|
||||
int height = 32 << ((header >> 17) & 0x7);
|
||||
int xpos = (header & 0x3f) * 32;
|
||||
@ -719,8 +665,8 @@ static void real3d_upload_texture(running_machine &machine, UINT32 header, UINT3
|
||||
{
|
||||
case 0x00: /* Texture with mipmaps */
|
||||
//if(bitdepth) {
|
||||
write_texture16(state, xpos, ypos, width, height, page, (UINT16*)data);
|
||||
invalidate_texture(machine, page, header & 0x3f, (header >> 7) & 0x1f, (header >> 14) & 0x7, (header >> 17) & 0x7);
|
||||
write_texture16(xpos, ypos, width, height, page, (UINT16*)data);
|
||||
invalidate_texture(page, header & 0x3f, (header >> 7) & 0x1f, (header >> 14) & 0x7, (header >> 17) & 0x7);
|
||||
//} else {
|
||||
/* TODO: 8-bit textures are weird. need to figure out some additional bits */
|
||||
//logerror("W: %d, H: %d, X: %d, Y: %d, P: %d, Bit: %d, : %08X, %08X\n", width, height, xpos, ypos, page, bitdepth, header & 0x00681040, header);
|
||||
@ -729,8 +675,8 @@ static void real3d_upload_texture(running_machine &machine, UINT32 header, UINT3
|
||||
break;
|
||||
case 0x01: /* Texture without mipmaps */
|
||||
//if(bitdepth) {
|
||||
write_texture16(state, xpos, ypos, width, height, page, (UINT16*)data);
|
||||
invalidate_texture(machine, page, header & 0x3f, (header >> 7) & 0x1f, (header >> 14) & 0x7, (header >> 17) & 0x7);
|
||||
write_texture16(xpos, ypos, width, height, page, (UINT16*)data);
|
||||
invalidate_texture(page, header & 0x3f, (header >> 7) & 0x1f, (header >> 14) & 0x7, (header >> 17) & 0x7);
|
||||
//} else {
|
||||
/* TODO: 8-bit textures are weird. need to figure out some additional bits */
|
||||
//logerror("W: %d, H: %d, X: %d, Y: %d, P: %d, Bit: %d, : %08X, %08X\n", width, height, xpos, ypos, page, bitdepth, header & 0x00681040, header);
|
||||
@ -757,15 +703,15 @@ void model3_state::real3d_display_list_end()
|
||||
{
|
||||
int length = (m_texture_fifo[i] / 2) + 2;
|
||||
UINT32 header = m_texture_fifo[i+1];
|
||||
real3d_upload_texture(machine(), header, &m_texture_fifo[i+2]);
|
||||
real3d_upload_texture(header, &m_texture_fifo[i+2]);
|
||||
i += length;
|
||||
};
|
||||
}
|
||||
m_texture_fifo_pos = 0;
|
||||
m_zbuffer.fill(0);
|
||||
m_bitmap3d.fill(0x8000);
|
||||
real3d_traverse_display_list(machine());
|
||||
//state->m_real3d_display_list = 1;
|
||||
real3d_traverse_display_list();
|
||||
//m_real3d_display_list = 1;
|
||||
}
|
||||
|
||||
void model3_state::real3d_display_list1_dma(UINT32 src, UINT32 dst, int length, int byteswap)
|
||||
@ -815,7 +761,7 @@ void model3_state::real3d_vrom_texture_dma(UINT32 src, UINT32 dst, int length, i
|
||||
address = space.read_dword((src+0));
|
||||
header = space.read_dword((src+4));
|
||||
}
|
||||
real3d_upload_texture(space.machine(), header, (UINT32*)&m_vrom[address]);
|
||||
real3d_upload_texture(header, (UINT32*)&m_vrom[address]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -897,11 +843,10 @@ static void matrix_multiply(MATRIX a, MATRIX b, MATRIX *out)
|
||||
memcpy(out, &tmp, sizeof(MATRIX));
|
||||
}
|
||||
|
||||
static void init_matrix_stack(running_machine &machine)
|
||||
void model3_state::init_matrix_stack()
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
MATRIX *matrix_stack;
|
||||
matrix_stack = state->m_matrix_stack = auto_alloc_array_clear(machine, MATRIX, MATRIX_STACK_SIZE);
|
||||
matrix_stack = m_matrix_stack = auto_alloc_array_clear(machine(), MATRIX, MATRIX_STACK_SIZE);
|
||||
|
||||
/* initialize the first matrix as identity */
|
||||
matrix_stack[0][0][0] = 1.0f;
|
||||
@ -921,36 +866,36 @@ static void init_matrix_stack(running_machine &machine)
|
||||
matrix_stack[0][3][2] = 0.0f;
|
||||
matrix_stack[0][3][3] = 1.0f;
|
||||
|
||||
state->m_matrix_stack_ptr = 0;
|
||||
m_matrix_stack_ptr = 0;
|
||||
}
|
||||
|
||||
static void get_top_matrix(model3_state *state, MATRIX *out)
|
||||
void model3_state::get_top_matrix(MATRIX *out)
|
||||
{
|
||||
memcpy( out, &state->m_matrix_stack[state->m_matrix_stack_ptr], sizeof(MATRIX));
|
||||
memcpy(out, &m_matrix_stack[m_matrix_stack_ptr], sizeof(MATRIX));
|
||||
}
|
||||
|
||||
static void push_matrix_stack(model3_state *state)
|
||||
void model3_state::push_matrix_stack()
|
||||
{
|
||||
state->m_matrix_stack_ptr++;
|
||||
if (state->m_matrix_stack_ptr >= MATRIX_STACK_SIZE)
|
||||
m_matrix_stack_ptr++;
|
||||
if (m_matrix_stack_ptr >= MATRIX_STACK_SIZE)
|
||||
fatalerror("push_matrix_stack: matrix stack overflow\n");
|
||||
|
||||
memcpy( &state->m_matrix_stack[state->m_matrix_stack_ptr], &state->m_matrix_stack[state->m_matrix_stack_ptr-1], sizeof(MATRIX));
|
||||
memcpy(&m_matrix_stack[m_matrix_stack_ptr], &m_matrix_stack[m_matrix_stack_ptr - 1], sizeof(MATRIX));
|
||||
}
|
||||
|
||||
static void pop_matrix_stack(model3_state *state)
|
||||
void model3_state::pop_matrix_stack()
|
||||
{
|
||||
state->m_matrix_stack_ptr--;
|
||||
if (state->m_matrix_stack_ptr < 0)
|
||||
m_matrix_stack_ptr--;
|
||||
if (m_matrix_stack_ptr < 0)
|
||||
fatalerror("pop_matrix_stack: matrix stack underflow\n");
|
||||
}
|
||||
|
||||
static void multiply_matrix_stack(model3_state *state, MATRIX matrix)
|
||||
void model3_state::multiply_matrix_stack(MATRIX matrix)
|
||||
{
|
||||
matrix_multiply(matrix, state->m_matrix_stack[state->m_matrix_stack_ptr], &state->m_matrix_stack[state->m_matrix_stack_ptr]);
|
||||
matrix_multiply(matrix, m_matrix_stack[m_matrix_stack_ptr], &m_matrix_stack[m_matrix_stack_ptr]);
|
||||
}
|
||||
|
||||
static void translate_matrix_stack(model3_state *state, float x, float y, float z)
|
||||
void model3_state::translate_matrix_stack(float x, float y, float z)
|
||||
{
|
||||
MATRIX tm;
|
||||
|
||||
@ -959,7 +904,7 @@ static void translate_matrix_stack(model3_state *state, float x, float y, float
|
||||
tm[2][0] = 0.0f; tm[2][1] = 0.0f; tm[2][2] = 1.0f; tm[2][3] = 0.0f;
|
||||
tm[3][0] = x; tm[3][1] = y; tm[3][2] = z; tm[3][3] = 1.0f;
|
||||
|
||||
matrix_multiply(tm, state->m_matrix_stack[state->m_matrix_stack_ptr], &state->m_matrix_stack[state->m_matrix_stack_ptr]);
|
||||
matrix_multiply(tm, m_matrix_stack[m_matrix_stack_ptr], &m_matrix_stack[m_matrix_stack_ptr]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -1037,17 +982,16 @@ static int clip_polygon(const poly_vertex *v, int num_vertices, PLANE cp, poly_v
|
||||
return clip_verts;
|
||||
}
|
||||
|
||||
static void render_one(running_machine &machine, TRIANGLE *tri)
|
||||
void model3_state::render_one(TRIANGLE *tri)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(state->m_poly);
|
||||
poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(m_poly);
|
||||
poly_draw_scanline_func callback = NULL;
|
||||
|
||||
tri->v[0].pz = 1.0f / tri->v[0].pz;
|
||||
tri->v[1].pz = 1.0f / tri->v[1].pz;
|
||||
tri->v[2].pz = 1.0f / tri->v[2].pz;
|
||||
|
||||
extra->zbuffer = &state->m_zbuffer;
|
||||
extra->zbuffer = &m_zbuffer;
|
||||
if (tri->param & TRI_PARAM_TEXTURE_ENABLE)
|
||||
{
|
||||
tri->v[0].pu = tri->v[0].pu * tri->v[0].pz * 256.0f;
|
||||
@ -1057,7 +1001,7 @@ static void render_one(running_machine &machine, TRIANGLE *tri)
|
||||
tri->v[2].pu = tri->v[2].pu * tri->v[2].pz * 256.0f;
|
||||
tri->v[2].pv = tri->v[2].pv * tri->v[2].pz * 256.0f;
|
||||
|
||||
extra->texture = get_texture(machine, (tri->param & TRI_PARAM_TEXTURE_PAGE) ? 1 : 0, tri->texture_x, tri->texture_y, tri->texture_width, tri->texture_height, tri->texture_format);
|
||||
extra->texture = get_texture((tri->param & TRI_PARAM_TEXTURE_PAGE) ? 1 : 0, tri->texture_x, tri->texture_y, tri->texture_width, tri->texture_height, tri->texture_format);
|
||||
extra->texture_param = tri->param;
|
||||
extra->polygon_transparency = tri->transparency;
|
||||
extra->polygon_intensity = tri->intensity;
|
||||
@ -1068,7 +1012,7 @@ static void render_one(running_machine &machine, TRIANGLE *tri)
|
||||
callback = (tri->transparency >= 32) ? draw_scanline_normal : draw_scanline_trans;
|
||||
else
|
||||
callback = draw_scanline_alpha;
|
||||
poly_render_triangle(state->m_poly, &state->m_bitmap3d, state->m_clip3d, callback, 3, &tri->v[0], &tri->v[1], &tri->v[2]);
|
||||
poly_render_triangle(m_poly, &m_bitmap3d, m_clip3d, callback, 3, &tri->v[0], &tri->v[1], &tri->v[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1076,14 +1020,13 @@ static void render_one(running_machine &machine, TRIANGLE *tri)
|
||||
extra->polygon_intensity = tri->intensity;
|
||||
extra->color = tri->color;
|
||||
|
||||
poly_render_triangle(state->m_poly, &state->m_bitmap3d, state->m_clip3d, draw_scanline_color, 1, &tri->v[0], &tri->v[1], &tri->v[2]);
|
||||
poly_render_triangle(m_poly, &m_bitmap3d, m_clip3d, draw_scanline_color, 1, &tri->v[0], &tri->v[1], &tri->v[2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_model(running_machine &machine, UINT32 addr)
|
||||
void model3_state::draw_model(UINT32 addr)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
UINT32 *model = (addr >= 0x100000) ? &state->m_vrom[addr] : &state->m_polygon_ram[addr];
|
||||
UINT32 *model = (addr >= 0x100000) ? &m_vrom[addr] : &m_polygon_ram[addr];
|
||||
UINT32 header[7];
|
||||
int index = 0;
|
||||
int last_polygon = FALSE, first_polygon = TRUE, back_face = FALSE;
|
||||
@ -1097,17 +1040,17 @@ static void draw_model(running_machine &machine, UINT32 addr)
|
||||
MATRIX transform_matrix;
|
||||
float center_x, center_y;
|
||||
|
||||
if(state->m_step < 0x15) { /* position coordinates are 17.15 fixed-point in Step 1.0 */
|
||||
if(m_step < 0x15) { /* position coordinates are 17.15 fixed-point in Step 1.0 */
|
||||
fixed_point_fraction = 1.0f / 32768.0f;
|
||||
} else { /* 13.19 fixed-point in other Steps */
|
||||
fixed_point_fraction = 1.0f / 524288.0f;
|
||||
}
|
||||
|
||||
get_top_matrix(state, &transform_matrix);
|
||||
get_top_matrix(&transform_matrix);
|
||||
|
||||
/* current viewport center coordinates on screen */
|
||||
center_x = (float)(state->m_viewport_region_x + (state->m_viewport_region_width / 2));
|
||||
center_y = (float)(state->m_viewport_region_y + (state->m_viewport_region_height / 2));
|
||||
center_x = (float)(m_viewport_region_x + (m_viewport_region_width / 2));
|
||||
center_y = (float)(m_viewport_region_y + (m_viewport_region_height / 2));
|
||||
|
||||
memset(prev_vertex, 0, sizeof(prev_vertex));
|
||||
|
||||
@ -1224,9 +1167,9 @@ static void draw_model(running_machine &machine, UINT32 addr)
|
||||
(normal[1] * transform_matrix[1][2]) +
|
||||
(normal[2] * transform_matrix[2][2]);
|
||||
|
||||
sn[0] *= state->m_coordinate_system[0][1];
|
||||
sn[1] *= state->m_coordinate_system[1][2];
|
||||
sn[2] *= state->m_coordinate_system[2][0];
|
||||
sn[0] *= m_coordinate_system[0][1];
|
||||
sn[1] *= m_coordinate_system[1][2];
|
||||
sn[2] *= m_coordinate_system[2][0];
|
||||
|
||||
/* TODO: depth bias */
|
||||
/* transform vertices */
|
||||
@ -1243,19 +1186,19 @@ static void draw_model(running_machine &machine, UINT32 addr)
|
||||
matrix_multiply_vector(transform_matrix, vect, &p[i]);
|
||||
|
||||
/* apply coordinate system */
|
||||
clip_vert[i].x = p[i][0] * state->m_coordinate_system[0][1];
|
||||
clip_vert[i].y = p[i][1] * state->m_coordinate_system[1][2];
|
||||
clip_vert[i].pz = p[i][2] * state->m_coordinate_system[2][0];
|
||||
clip_vert[i].x = p[i][0] * m_coordinate_system[0][1];
|
||||
clip_vert[i].y = p[i][1] * m_coordinate_system[1][2];
|
||||
clip_vert[i].pz = p[i][2] * m_coordinate_system[2][0];
|
||||
clip_vert[i].pu = vertex[i].pu * texture_coord_scale;
|
||||
clip_vert[i].pv = vertex[i].pv * texture_coord_scale;
|
||||
}
|
||||
|
||||
/* clip against view frustum */
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, state->m_clip_plane[0], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, state->m_clip_plane[1], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, state->m_clip_plane[2], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, state->m_clip_plane[3], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, state->m_clip_plane[4], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, m_clip_plane[0], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, m_clip_plane[1], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, m_clip_plane[2], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, m_clip_plane[3], clip_vert);
|
||||
num_vertices = clip_polygon(clip_vert, num_vertices, m_clip_plane[4], clip_vert);
|
||||
|
||||
/* backface culling */
|
||||
if( (header[6] & 0x800000) && (!(header[1] & 0x0010)) ) {
|
||||
@ -1271,15 +1214,15 @@ static void draw_model(running_machine &machine, UINT32 addr)
|
||||
/* homogeneous Z-divide, screen-space transformation */
|
||||
for(i=0; i < num_vertices; i++) {
|
||||
float ooz = 1.0f / clip_vert[i].pz;
|
||||
clip_vert[i].x = ((clip_vert[i].x * ooz) * state->m_viewport_focal_length) + center_x;
|
||||
clip_vert[i].y = ((clip_vert[i].y * ooz) * state->m_viewport_focal_length) + center_y;
|
||||
clip_vert[i].x = ((clip_vert[i].x * ooz) * m_viewport_focal_length) + center_x;
|
||||
clip_vert[i].y = ((clip_vert[i].y * ooz) * m_viewport_focal_length) + center_y;
|
||||
}
|
||||
|
||||
// lighting
|
||||
if ((header[6] & 0x10000) == 0)
|
||||
{
|
||||
dot = dot_product3(sn, state->m_parallel_light);
|
||||
intensity = ((dot * state->m_parallel_light_intensity) + state->m_ambient_light_intensity) * 256.0f;
|
||||
dot = dot_product3(sn, m_parallel_light);
|
||||
intensity = ((dot * m_parallel_light_intensity) + m_ambient_light_intensity) * 256.0f;
|
||||
if (intensity > 256)
|
||||
{
|
||||
intensity = 256;
|
||||
@ -1316,7 +1259,7 @@ static void draw_model(running_machine &machine, UINT32 addr)
|
||||
tri.param |= (header[2] & 0x1) ? TRI_PARAM_TEXTURE_MIRROR_V : 0;
|
||||
tri.param |= (header[6] & 0x80000000) ? TRI_PARAM_ALPHA_TEST : 0;
|
||||
|
||||
render_one(machine, &tri);
|
||||
render_one(&tri);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1326,27 +1269,27 @@ static void draw_model(running_machine &machine, UINT32 addr)
|
||||
/*****************************************************************************/
|
||||
/* display list parser */
|
||||
|
||||
static UINT32 *get_memory_pointer(model3_state *state, UINT32 address)
|
||||
UINT32 *model3_state::get_memory_pointer(UINT32 address)
|
||||
{
|
||||
if (address & 0x800000)
|
||||
{
|
||||
if (address >= 0x840000) {
|
||||
fatalerror("get_memory_pointer: invalid display list memory address %08X\n", address);
|
||||
}
|
||||
return &state->m_display_list_ram[address & 0x7fffff];
|
||||
return &m_display_list_ram[address & 0x7fffff];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address >= 0x100000) {
|
||||
fatalerror("get_memory_pointer: invalid node ram address %08X\n", address);
|
||||
}
|
||||
return &state->m_culling_ram[address];
|
||||
return &m_culling_ram[address];
|
||||
}
|
||||
}
|
||||
|
||||
static void load_matrix(model3_state *state, int matrix_num, MATRIX *out)
|
||||
void model3_state::load_matrix(int matrix_num, MATRIX *out)
|
||||
{
|
||||
float *matrix = (float *)get_memory_pointer(state, state->m_matrix_base_address + matrix_num * 12);
|
||||
float *matrix = (float *)get_memory_pointer(m_matrix_base_address + matrix_num * 12);
|
||||
|
||||
(*out)[0][0] = matrix[3]; (*out)[0][1] = matrix[6]; (*out)[0][2] = matrix[9]; (*out)[0][3] = 0.0f;
|
||||
(*out)[1][0] = matrix[4]; (*out)[1][1] = matrix[7]; (*out)[1][2] = matrix[10]; (*out)[1][3] = 0.0f;
|
||||
@ -1354,27 +1297,24 @@ static void load_matrix(model3_state *state, int matrix_num, MATRIX *out)
|
||||
(*out)[3][0] = matrix[0]; (*out)[3][1] = matrix[1]; (*out)[3][2] = matrix[2]; (*out)[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
static void traverse_list4(running_machine &machine, int lod_num, UINT32 address)
|
||||
void model3_state::traverse_list4(int lod_num, UINT32 address)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
|
||||
/* does something with the LOD selection */
|
||||
UINT32 *list = get_memory_pointer(state, address);
|
||||
UINT32 *list = get_memory_pointer(address);
|
||||
UINT32 link = list[0];
|
||||
|
||||
draw_model(machine, link & 0xffffff);
|
||||
draw_model(link & 0xffffff);
|
||||
}
|
||||
|
||||
static void traverse_list(running_machine &machine, UINT32 address)
|
||||
void model3_state::traverse_list(UINT32 address)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
UINT32 *list = get_memory_pointer(state, address);
|
||||
UINT32 *list = get_memory_pointer(address);
|
||||
int list_ptr = 0;
|
||||
|
||||
if (state->m_list_depth > 2)
|
||||
if (m_list_depth > 2)
|
||||
return;
|
||||
|
||||
state->m_list_depth++;
|
||||
m_list_depth++;
|
||||
|
||||
/* find the end of the list */
|
||||
while (1)
|
||||
@ -1395,29 +1335,29 @@ static void traverse_list(running_machine &machine, UINT32 address)
|
||||
address = list[--list_ptr] & 0xffffff;
|
||||
if (address != 0 && address != 0x800800)
|
||||
//if (address != 0)
|
||||
draw_block(machine, address);
|
||||
draw_block(address);
|
||||
}
|
||||
|
||||
state->m_list_depth--;
|
||||
m_list_depth--;
|
||||
}
|
||||
|
||||
INLINE void process_link(running_machine &machine, UINT32 address, UINT32 link)
|
||||
inline void model3_state::process_link(UINT32 address, UINT32 link)
|
||||
{
|
||||
if (link != 0 && link != 0x0fffffff && link != 0x00800800 && link != 0x01000000)
|
||||
{
|
||||
switch (link >> 24)
|
||||
{
|
||||
case 0x00: /* link to another node */
|
||||
draw_block(machine, link & 0xffffff);
|
||||
draw_block(link & 0xffffff);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case 0x03: /* both of these link to models, is there any difference ? */
|
||||
draw_model(machine, link & 0xffffff);
|
||||
draw_model(link & 0xffffff);
|
||||
break;
|
||||
|
||||
case 0x04: /* list of links */
|
||||
traverse_list(machine, link & 0xffffff);
|
||||
traverse_list(link & 0xffffff);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1427,52 +1367,50 @@ INLINE void process_link(running_machine &machine, UINT32 address, UINT32 link)
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_block(running_machine &machine, UINT32 address)
|
||||
void model3_state::draw_block(UINT32 address)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
const UINT32 *node = get_memory_pointer(state, address);
|
||||
const UINT32 *node = get_memory_pointer(address);
|
||||
UINT32 link;
|
||||
int node_matrix;
|
||||
float x, y, z;
|
||||
MATRIX matrix;
|
||||
int offset;
|
||||
|
||||
offset = (state->m_step < 0x15) ? 2 : 0;
|
||||
offset = (m_step < 0x15) ? 2 : 0;
|
||||
link = node[7 - offset];
|
||||
|
||||
/* apply matrix and translation */
|
||||
node_matrix = node[3 - offset] & 0xfff;
|
||||
load_matrix(state, node_matrix, &matrix);
|
||||
load_matrix(node_matrix, &matrix);
|
||||
|
||||
push_matrix_stack(state);
|
||||
push_matrix_stack();
|
||||
|
||||
if (node[0] & 0x10)
|
||||
{
|
||||
x = *(float *)&node[4 - offset];
|
||||
y = *(float *)&node[5 - offset];
|
||||
z = *(float *)&node[6 - offset];
|
||||
translate_matrix_stack(state, x, y, z);
|
||||
translate_matrix_stack(x, y, z);
|
||||
}
|
||||
else if (node_matrix != 0)
|
||||
multiply_matrix_stack(state, matrix);
|
||||
multiply_matrix_stack(matrix);
|
||||
|
||||
/* bit 0x08 of word 0 indicates a pointer list */
|
||||
if (node[0] & 0x08)
|
||||
traverse_list4(machine, (node[3 - offset] >> 12) & 0x7f, link & 0xffffff);
|
||||
traverse_list4((node[3 - offset] >> 12) & 0x7f, link & 0xffffff);
|
||||
else
|
||||
process_link(machine, address, link);
|
||||
process_link(address, link);
|
||||
|
||||
pop_matrix_stack(state);
|
||||
pop_matrix_stack();
|
||||
|
||||
/* handle the second link */
|
||||
link = node[8 - offset];
|
||||
process_link(machine, address, link);
|
||||
process_link(address, link);
|
||||
}
|
||||
|
||||
static void draw_viewport(running_machine &machine, int pri, UINT32 address)
|
||||
void model3_state::draw_viewport(int pri, UINT32 address)
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
const UINT32 *node = get_memory_pointer(state, address);
|
||||
const UINT32 *node = get_memory_pointer(address);
|
||||
UINT32 link_address;
|
||||
float /*viewport_left, viewport_right, */viewport_top, viewport_bottom;
|
||||
float /*fov_x,*/ fov_y;
|
||||
@ -1484,17 +1422,17 @@ static void draw_viewport(running_machine &machine, int pri, UINT32 address)
|
||||
/* traverse to the link node before drawing this viewport */
|
||||
/* check this is correct as this affects the rendering order */
|
||||
if (link_address != 0x01000000)
|
||||
draw_viewport(machine, pri, link_address);
|
||||
draw_viewport(pri, link_address);
|
||||
|
||||
/* skip if this isn't the right priority */
|
||||
if (pri != ((node[0] >> 3) & 3))
|
||||
return;
|
||||
|
||||
/* set viewport parameters */
|
||||
state->m_viewport_region_x = (node[26] & 0xffff) >> 4; /* 12.4 fixed point */
|
||||
state->m_viewport_region_y = ((node[26] >> 16) & 0xffff) >> 4;
|
||||
state->m_viewport_region_width = (node[20] & 0xffff) >> 2; /* 14.2 fixed point */
|
||||
state->m_viewport_region_height = ((node[20] >> 16) & 0xffff) >> 2;
|
||||
m_viewport_region_x = (node[26] & 0xffff) >> 4; /* 12.4 fixed point */
|
||||
m_viewport_region_y = ((node[26] >> 16) & 0xffff) >> 4;
|
||||
m_viewport_region_width = (node[20] & 0xffff) >> 2; /* 14.2 fixed point */
|
||||
m_viewport_region_height = ((node[20] >> 16) & 0xffff) >> 2;
|
||||
|
||||
/* frustum plane angles */
|
||||
//viewport_left = RADIAN_TO_DEGREE(asin(*(float *)&node[12]));
|
||||
@ -1503,44 +1441,41 @@ static void draw_viewport(running_machine &machine, int pri, UINT32 address)
|
||||
viewport_bottom = RADIAN_TO_DEGREE(asin(*(float *)&node[18]));
|
||||
|
||||
/* build clipping planes */
|
||||
state->m_clip_plane[0].x = *(float *)&node[13]; state->m_clip_plane[0].y = 0.0f; state->m_clip_plane[0].z = *(float *)&node[12]; state->m_clip_plane[0].d = 0.0f;
|
||||
state->m_clip_plane[1].x = *(float *)&node[17]; state->m_clip_plane[1].y = 0.0f; state->m_clip_plane[1].z = *(float *)&node[16]; state->m_clip_plane[1].d = 0.0f;
|
||||
state->m_clip_plane[2].x = 0.0f; state->m_clip_plane[2].y = *(float *)&node[15]; state->m_clip_plane[2].z = *(float *)&node[14]; state->m_clip_plane[2].d = 0.0f;
|
||||
state->m_clip_plane[3].x = 0.0f; state->m_clip_plane[3].y = *(float *)&node[19]; state->m_clip_plane[3].z = *(float *)&node[18]; state->m_clip_plane[3].d = 0.0f;
|
||||
state->m_clip_plane[4].x = 0.0f; state->m_clip_plane[4].y = 0.0f; state->m_clip_plane[4].z = 1.0f; state->m_clip_plane[4].d = 1.0f;
|
||||
m_clip_plane[0].x = *(float *)&node[13]; m_clip_plane[0].y = 0.0f; m_clip_plane[0].z = *(float *)&node[12]; m_clip_plane[0].d = 0.0f;
|
||||
m_clip_plane[1].x = *(float *)&node[17]; m_clip_plane[1].y = 0.0f; m_clip_plane[1].z = *(float *)&node[16]; m_clip_plane[1].d = 0.0f;
|
||||
m_clip_plane[2].x = 0.0f; m_clip_plane[2].y = *(float *)&node[15]; m_clip_plane[2].z = *(float *)&node[14]; m_clip_plane[2].d = 0.0f;
|
||||
m_clip_plane[3].x = 0.0f; m_clip_plane[3].y = *(float *)&node[19]; m_clip_plane[3].z = *(float *)&node[18]; m_clip_plane[3].d = 0.0f;
|
||||
m_clip_plane[4].x = 0.0f; m_clip_plane[4].y = 0.0f; m_clip_plane[4].z = 1.0f; m_clip_plane[4].d = 1.0f;
|
||||
|
||||
/* compute field of view */
|
||||
//fov_x = viewport_left + viewport_right;
|
||||
fov_y = viewport_top + viewport_bottom;
|
||||
state->m_viewport_focal_length = (state->m_viewport_region_height / 2) / tan( (fov_y * M_PI / 180.0f) / 2.0f );
|
||||
m_viewport_focal_length = (m_viewport_region_height / 2) / tan( (fov_y * M_PI / 180.0f) / 2.0f );
|
||||
|
||||
state->m_matrix_base_address = node[22];
|
||||
m_matrix_base_address = node[22];
|
||||
/* TODO: where does node[23] point to ? LOD table ? */
|
||||
|
||||
/* set lighting parameters */
|
||||
state->m_parallel_light[0] = -*(float *)&node[5];
|
||||
state->m_parallel_light[1] = *(float *)&node[6];
|
||||
state->m_parallel_light[2] = *(float *)&node[4];
|
||||
state->m_parallel_light_intensity = *(float *)&node[7];
|
||||
state->m_ambient_light_intensity = (UINT8)(node[36] >> 8) / 256.0f;
|
||||
m_parallel_light[0] = -*(float *)&node[5];
|
||||
m_parallel_light[1] = *(float *)&node[6];
|
||||
m_parallel_light[2] = *(float *)&node[4];
|
||||
m_parallel_light_intensity = *(float *)&node[7];
|
||||
m_ambient_light_intensity = (UINT8)(node[36] >> 8) / 256.0f;
|
||||
|
||||
/* set coordinate system matrix */
|
||||
load_matrix(state, 0, &state->m_coordinate_system);
|
||||
load_matrix(0, &m_coordinate_system);
|
||||
|
||||
/* process a link */
|
||||
process_link(machine, link_address, node[2]);
|
||||
process_link(link_address, node[2]);
|
||||
}
|
||||
|
||||
|
||||
static void real3d_traverse_display_list(running_machine &machine)
|
||||
void model3_state::real3d_traverse_display_list()
|
||||
{
|
||||
model3_state *state = machine.driver_data<model3_state>();
|
||||
int pri;
|
||||
init_matrix_stack();
|
||||
|
||||
init_matrix_stack(machine);
|
||||
for (int pri = 0; pri < 4; pri++)
|
||||
draw_viewport(pri, 0x800000);
|
||||
|
||||
for (pri = 0; pri < 4; pri++)
|
||||
draw_viewport(machine, pri, 0x800000);
|
||||
|
||||
poly_wait(state->m_poly, "real3d_traverse_display_list");
|
||||
poly_wait(m_poly, "real3d_traverse_display_list");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user