diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/video/zeus2.cpp | 1328 | ||||
-rw-r--r-- | src/devices/video/zeus2.h | 55 |
2 files changed, 703 insertions, 680 deletions
diff --git a/src/devices/video/zeus2.cpp b/src/devices/video/zeus2.cpp index 50c384f6a0c..cc6f6a8a6b5 100644 --- a/src/devices/video/zeus2.cpp +++ b/src/devices/video/zeus2.cpp @@ -90,7 +90,7 @@ void zeus2_device::device_start() //printf("%s\n", machine().system().name); // Set system type - if (strcmp(machine().system().name, "thegrid") == 0) { + if (strcmp(machine().system().name, "thegrid") == 0 || strcmp(machine().system().name, "thegrida") == 0) { m_system = THEGRID; } else if (strcmp(machine().system().name, "crusnexo") == 0) { @@ -114,8 +114,8 @@ void zeus2_device::device_start() save_item(NAME(zeus_cliprect.min_y)); save_item(NAME(zeus_cliprect.max_y)); save_item(NAME(zeus_matrix)); - save_item(NAME(zeus_point)); - save_item(NAME(zeus_point2)); + save_item(NAME(zeus_trans)); + save_item(NAME(zeus_light)); save_item(NAME(zeus_texbase)); save_item(NAME(zeus_quad_size)); save_item(NAME(m_fill_color)); @@ -140,6 +140,7 @@ void zeus2_device::device_reset() zeus_fifo_words = 0; m_fill_color = 0; m_fill_depth = 0; + m_texmodeReg = 0; } #if DUMP_WAVE_RAM #include <iostream> @@ -210,8 +211,6 @@ uint32_t zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap int x, y; - poly->wait("SCREEN_UPDATE"); - //if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x10 : 1; popmessage("Zbase = %f", (double)zbase); } //if (machine().input().code_pressed(KEYCODE_UP)) { zbase -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x10 : 1; popmessage("Zbase = %f", (double)zbase); } @@ -333,8 +332,8 @@ WRITE32_MEMBER( zeus2_device::zeus2_w ) { int logit = (offset != 0x08 && (offset != 0x20 || data != 0) && - offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e - && offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e + offset != 0x48 && offset != 0x49 && offset != 0x40 && offset != 0x41 && offset != 0x4e && + offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e ); logit &= LOG_REGS; if (logit) @@ -401,147 +400,176 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log /* handle the writes; only trigger on low accesses */ switch (offset) { - case 0x08: - zeus_fifo[zeus_fifo_words++] = m_zeusbase[0x08]; - if (zeus2_fifo_process(zeus_fifo, zeus_fifo_words)) - zeus_fifo_words = 0; + case 0x08: + zeus_fifo[zeus_fifo_words++] = m_zeusbase[0x08]; + if (zeus2_fifo_process(zeus_fifo, zeus_fifo_words)) + zeus_fifo_words = 0; - /* set the interrupt signal to indicate we can handle more */ - int_timer->adjust(attotime::from_nsec(500)); - break; + /* set the interrupt signal to indicate we can handle more */ + int_timer->adjust(attotime::from_nsec(500)); + break; - case 0x10: - // BITS 11 - 10 COL SIZE / BANK FOR WR1 - // BITS 9 - 8 COL SIZE / BANK FOR WR0 - if (logit) logerror("\tSys Setup"); - if (m_zeusbase[0x10] & 0x20) - { - m_yScale = (((m_zeusbase[0x39] >> 16) & 0xfff) < 0x100) ? 0 : 1; - int hor = ((m_zeusbase[0x34] & 0xffff) - (m_zeusbase[0x33] >> 16)) << m_yScale; - int ver = ((m_zeusbase[0x35] & 0xffff) + 1) << m_yScale; - popmessage("reg[30]: %08X Screen: %dH X %dV yScale: %d", m_zeusbase[0x30], hor, ver, m_yScale); - int vtotal = (m_zeusbase[0x37] & 0xffff) << m_yScale; - int htotal = (m_zeusbase[0x34] >> 16) << m_yScale; - //rectangle visarea((m_zeusbase[0x33] >> 16) << m_yScale, htotal - 1, 0, (m_zeusbase[0x35] & 0xffff) << m_yScale); - rectangle visarea(0, hor-1, 0, ver-1); - m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS((double)ZEUS2_VIDEO_CLOCK / 4.0 / (htotal * vtotal))); - zeus_cliprect = visarea; - zeus_cliprect.max_x -= zeus_cliprect.min_x; - zeus_cliprect.min_x = 0; - // Startup vblank timer - vblank_timer->adjust(attotime::from_usec(1)); - } - break; + case 0x10: + // BITS 11 - 10 COL SIZE / BANK FOR WR1 + // BITS 9 - 8 COL SIZE / BANK FOR WR0 + if (logit) logerror("\tSys Setup"); + if (m_zeusbase[0x10] & 0x20) + { + m_yScale = (((m_zeusbase[0x39] >> 16) & 0xfff) < 0x100) ? 0 : 1; + int hor = ((m_zeusbase[0x34] & 0xffff) - (m_zeusbase[0x33] >> 16)) << m_yScale; + int ver = ((m_zeusbase[0x35] & 0xffff) + 1) << m_yScale; + popmessage("reg[30]: %08X Screen: %dH X %dV yScale: %d", m_zeusbase[0x30], hor, ver, m_yScale); + int vtotal = (m_zeusbase[0x37] & 0xffff) << m_yScale; + int htotal = (m_zeusbase[0x34] >> 16) << m_yScale; + //rectangle visarea((m_zeusbase[0x33] >> 16) << m_yScale, htotal - 1, 0, (m_zeusbase[0x35] & 0xffff) << m_yScale); + rectangle visarea(0, hor - 1, 0, ver - 1); + m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS((double)ZEUS2_VIDEO_CLOCK / 4.0 / (htotal * vtotal))); + zeus_cliprect = visarea; + zeus_cliprect.max_x -= zeus_cliprect.min_x; + zeus_cliprect.min_x = 0; + // Startup vblank timer + vblank_timer->adjust(attotime::from_usec(1)); + } + break; - case 0x11: - if (logit) logerror("\tHost Interface Setup"); - break; + case 0x11: + if (logit) logerror("\tHost Interface Setup"); + break; - case 0x12: - if (logit) logerror("\tPLL Setup"); - break; + case 0x12: + if (logit) logerror("\tPLL Setup"); + break; - case 0x13: - if (logit) logerror("\tZeus Test Out"); - break; + case 0x13: + if (logit) logerror("\tZeus Test Out"); + break; - case 0x20: - zeus2_pointer_write(m_zeusbase[0x20] >> 24, (m_zeusbase[0x20] & 0xffffff), logit); - break; + case 0x20: + zeus2_pointer_write(m_zeusbase[0x20] >> 24, (m_zeusbase[0x20] & 0xffffff), logit); + break; - case 0x22: - if (logit) logerror("\tRend Setup 0"); - break; + case 0x22: + if (logit) logerror("\tRend Setup 0"); + break; - case 0x23: - if (logit) logerror("\tRend Setup 1"); - break; + case 0x23: + if (logit) logerror("\tRend Setup 1"); + break; - case 0x24: - // 0x601 == test mode - if (logit) logerror("\tRend Setup 4"); - break; + case 0x24: + // 0x601 == test mode + if (logit) logerror("\tRend Setup 4"); + break; - case 0x2a: - // 0x000000c0 = bilinear off - if (logit) logerror("\tRend Force Off"); - break; + case 0x2a: + // 0x000000c0 = bilinear off + if (logit) logerror("\tRend Force Off"); + break; - case 0x2b: - if (logit) logerror("\tRend Force On"); - break; + case 0x2b: + if (logit) logerror("\tRend Force On"); + break; - case 0x2c: - if (logit) logerror("\tRend AE Flag"); - break; + case 0x2c: + if (logit) logerror("\tRend AE Flag"); + break; - case 0x2d: - if (logit) logerror("\tRend AF Flag"); - break; + case 0x2d: + if (logit) logerror("\tRend AF Flag"); + break; - case 0x2f: - if (logit) logerror("\tPixel Proc Setup"); - break; + case 0x2f: + if (logit) logerror("\tPixel Proc Setup"); + break; - case 0x30: - if (logit) logerror("\tCRT Controller Setup = %08X", m_zeusbase[offset]); - break; + case 0x30: + if (logit) logerror("\tCRT Controller Setup = %08X", m_zeusbase[offset]); + break; - case 0x31: - if (logit) logerror("\tDotClk Sel 1 : DotClk Sel 2 = %08X", m_zeusbase[offset]); - break; - case 0x32: - if (logit) logerror("\tHSync End = %i HSync Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); - break; - case 0x33: - if (logit) logerror("\tHBlank End = %i Update Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); - break; - case 0x34: - if (logit) logerror("\tHTotal = %i HBlank Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); - break; - case 0x35: - if (logit) logerror("\tVSync Start = %i VBlank Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); - break; - case 0x36: - if (logit) logerror("\tVTotal = %i VSync End = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); - break; - case 0x37: - if (logit) logerror("\tVTotal = %i", m_zeusbase[offset]); - break; - case 0x38: - { - uint32_t temp = m_zeusbase[0x38]; - m_zeusbase[0x38] = oldval; - m_screen->update_partial(m_screen->vpos()); - log_fifo = machine().input().code_pressed(KEYCODE_L) | ALWAYS_LOG_FIFO; - m_zeusbase[0x38] = temp; + case 0x31: + if (logit) logerror("\tDotClk Sel 1 : DotClk Sel 2 = %08X", m_zeusbase[offset]); + break; + case 0x32: + if (logit) logerror("\tHSync End = %i HSync Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); + break; + case 0x33: + if (logit) logerror("\tHBlank End = %i Update Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); + break; + case 0x34: + if (logit) logerror("\tHTotal = %i HBlank Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); + break; + case 0x35: + if (logit) logerror("\tVSync Start = %i VBlank Start = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); + break; + case 0x36: + if (logit) logerror("\tVTotal = %i VSync End = %i", (m_zeusbase[offset] >> 16), m_zeusbase[offset] & 0xffff); + break; + case 0x37: + if (logit) logerror("\tVTotal = %i", m_zeusbase[offset]); + break; + case 0x38: + { + uint32_t temp = m_zeusbase[0x38]; + m_zeusbase[0x38] = oldval; + m_screen->update_partial(m_screen->vpos()); + log_fifo = machine().input().code_pressed(KEYCODE_L) | ALWAYS_LOG_FIFO; + m_zeusbase[0x38] = temp; + } + break; + case 0x39: + if (logit) logerror("\tLine Length = %i FIFO AF = %i FIFO AE = %i", (m_zeusbase[offset] >> 16) & 0xfff, (m_zeusbase[offset] >> 8) & 0xff, m_zeusbase[offset] & 0xff); + break; + + case 0x40: case 0x41: case 0x48: case 0x49: case 0x4e: + if (offset == 0x41) { + // mwskinsa (atlantis) writes 0xffffffff and expects 0x1fff03ff to be read back + m_zeusbase[0x41] &= 0x1fff03ff; + } + /* + m_zeusbase[0x4e] : + bit 0 - 1 : which register triggers write through + bit 3 : enable write through via these registers + bit 4 : seems to be set during reads, when 0x41 is used for latching + bit 6 : enable autoincrement on write through + */ + if ((offset & 0xf) == (m_zeusbase[0x4e] & 0xf)) { + // If the address is auto-increment then don't load new value + // In reality address is latched by a write to 0x40 + if (offset == 0x41 && (m_zeusbase[0x4e] & 0x40)) { + m_zeusbase[0x41] = oldval; } - break; - case 0x39: - if (logit) logerror("\tLine Length = %i FIFO AF = %i FIFO AE = %i", (m_zeusbase[offset] >> 16) & 0xfff, (m_zeusbase[offset] >> 8) & 0xff, m_zeusbase[offset] & 0xff); - break; - case 0x40: - { int code = (m_zeusbase[0x40] >> 16) & 0xf; - if (code == 0x2) { - /* in direct mode it latches values */ - if ((m_zeusbase[0x4e] & 0x20)) - { - const void *src = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); - m_zeusbase[0x48] = WAVERAM_READ32(src, 0); - m_zeusbase[0x49] = WAVERAM_READ32(src, 1); + switch (code) { + case 0: + // NOP + break; + case 1: + // Special mode register write + //if (logit) + logerror("\t-- Special Mode Write: [4e]: %08X [40]: %08X [41]: %08x [48]: %08x [49]: %08x\n", code, m_zeusbase[0x4e], m_zeusbase[0x40], m_zeusbase[0x41], m_zeusbase[0x48], m_zeusbase[0x49]); + break; + case 2: + { + /* Read waveram0 */ + //if ((m_zeusbase[0x4e] & 0x20)) + //{ + const void *src = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); + m_zeusbase[0x48] = WAVERAM_READ32(src, 0); + m_zeusbase[0x49] = WAVERAM_READ32(src, 1); - if (m_zeusbase[0x4e] & 0x40) - { - m_zeusbase[0x41]++; - m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; - m_zeusbase[0x41] &= ~0xfc00; - } + if (m_zeusbase[0x4e] & 0x40) + { + m_zeusbase[0x41]++; + m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; + m_zeusbase[0x41] &= ~0xfc00; } + //} } - else if (code == 0x4) { + break; + case 4: + { // Load pal table from RGB555 if (logit) logerror("\t-- pal table rgb555 load: control: %08X addr: %08X", m_zeusbase[0x40], m_zeusbase[0x41]); @@ -551,7 +579,9 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log void *dataPtr = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); load_pal_table(dataPtr, m_zeusbase[0x40], 0, logit); } - else if (code == 0x5) { + break; + case 5: + { // Zeus microcode burst from waveram if (logit) logerror("\t-- ucode load: control: %08X addr: %08X", m_zeusbase[0x40], m_zeusbase[0x41]); @@ -582,6 +612,10 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log case 0x38850077: zeus_quad_size = 10; break; + case 0x388500be: + // The Grid direct rendering + zeus_quad_size = 512; + break; default: logerror(" default quad size 10\n"); zeus_quad_size = 10; @@ -597,30 +631,26 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log waveData = *wavePtr++; logerror(" %08X", waveData); waveData = *wavePtr++; + logerror(" %08X", waveData); //logerror(" %08X", waveData); if (0 && (i + 1) % 16 == 0) logerror("\n"); } - logerror("\n"); } } - else if (code == 0x6) { - // Zeus model fifo burst from waveram - } - else { - if (logit) - logerror("\t-- unknown burst: control: %08X addr: %08X", m_zeusbase[0x40], m_zeusbase[0x41]); - } - } - break; - case 0x41: - /* this is the address, except in read mode, where it latches values */ - if (m_zeusbase[0x4e] & 0x10) + break; + //case 6: { + // // Zeus model fifo burst from waveram + //} + //break; + case 9: { - const void *src = waveram0_ptr_from_expanded_addr(oldval); - m_zeusbase[0x41] = oldval; - m_zeusbase[0x48] = WAVERAM_READ32(src, 0); - m_zeusbase[0x49] = WAVERAM_READ32(src, 1); + // Waveram Write + void *dest = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); + WAVERAM_WRITE32(dest, 0, m_zeusbase[0x48]); + WAVERAM_WRITE32(dest, 1, m_zeusbase[0x49]); + if (logit) + logerror("\t[41]=%08X [4E]=%08X", m_zeusbase[0x41], m_zeusbase[0x4e]); if (m_zeusbase[0x4e] & 0x40) { @@ -628,209 +658,191 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; m_zeusbase[0x41] &= ~0xfc00; } - } else { - // mwskinsa (atlantis) writes 0xffffffff and expects 0x1fff03ff to be read back - m_zeusbase[0x41] &= 0x1fff03ff; } break; - - case 0x48: - case 0x49: - /* if we're in write mode, process it */ - if (m_zeusbase[0x40] == 0x00890000) + default: { - /* - m_zeusbase[0x4e]: - bit 0-1: which register triggers write through - bit 3: enable write through via these registers - bit 4: seems to be set during reads, when 0x41 is used for latching - bit 6: enable autoincrement on write through - */ - if ((m_zeusbase[0x4e] & 0x08) && (offset & 3) == (m_zeusbase[0x4e] & 3)) - { - void *dest = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); - WAVERAM_WRITE32(dest, 0, m_zeusbase[0x48]); - WAVERAM_WRITE32(dest, 1, m_zeusbase[0x49]); - if (logit) - logerror("\t[41]=%08X [4E]=%08X", m_zeusbase[0x41], m_zeusbase[0x4e]); - - if (m_zeusbase[0x4e] & 0x40) - { - m_zeusbase[0x41]++; - m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6; - m_zeusbase[0x41] &= ~0xfc00; - } - } + //if (logit) + logerror("\t-- unknown code (%d): [4e]: %08X [40]: %08X [41]: %08x [48]: %08x [49]: %08x\n", code, m_zeusbase[0x4e], m_zeusbase[0x40], m_zeusbase[0x41], m_zeusbase[0x48], m_zeusbase[0x49]); } - - /* make sure we log anything else */ - else if (logit) - logerror("\t[40]=%08X [4E]=%08X\n", m_zeusbase[0x40], m_zeusbase[0x4e]); break; + } + } + break; - case 0x50: case 0x51: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5e: - // m_zeusbase[0x5e]: - // bits 3:0 select which offset triggers an access - // bit 4: clear error - // bit 5: 24 bit (1) / 32 bit mode (0) - // bit 6: enable autoincrement wave address - // bit 7 autoincrement desination address? - // bit 8 autoincrement row/col address by 1 (0) or 2 (1) - if ((offset & 0xf) == (m_zeusbase[0x5e] & 0xf)) { - - int code = (m_zeusbase[0x50] >> 16) & 0xf; - - // If the address is auto-increment then don't load new value - // In reality address is latched by a write to 0x50 - if (offset == 0x51 && (m_zeusbase[0x5e] & 0x40)) { - m_zeusbase[0x51] = oldval; - } + case 0x50: case 0x51: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5e: + // m_zeusbase[0x5e]: + // bits 3:0 select which offset triggers an access + // bit 4: clear error + // bit 5: 24 bit (1) / 32 bit mode (0) + // bit 6: enable autoincrement wave address + // bit 7 autoincrement desination address? + // bit 8 autoincrement row/col address by 1 (0) or 2 (1) + if ((offset & 0xf) == (m_zeusbase[0x5e] & 0xf)) { + + int code = (m_zeusbase[0x50] >> 16) & 0xf; + + // If the address is auto-increment then don't load new value + // In reality address is latched by a write to 0x50 + if (offset == 0x51 && (m_zeusbase[0x5e] & 0x40)) { + m_zeusbase[0x51] = oldval; + } - switch (code) { - case 0: - // NOP - break; - case 1: - // SGRAM Special Mode Register Write - if (m_zeusbase[0x51] == 0x00200000) { - // SGRAM Mask Register - if ((m_zeusbase[0x58] & m_zeusbase[0x59] & m_zeusbase[0x5a]) != 0xffffffff) - logerror("zeus2_register_update: Warning! Mask Register not equal to 0xffffffff\n"); - } - if (m_zeusbase[0x51] == 0x00400000) { - // SGRAM Color Register - m_fill_color = m_zeusbase[0x58]; - m_fill_depth = ((m_zeusbase[0x5a] & 0xffff) << 16) | ((m_zeusbase[0x58] >> 24) << 8); - m_fill_depth >>= 8; // Sign extend down to 24 bits - if (m_zeusbase[0x58] != m_zeusbase[0x59]) - logerror("zeus2_register_update: Warning! Different fill colors are set.\n"); - } - break; - case 0x2: - frame_read(); - break; - case 0x8: - { - // Fast fill - // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame - // crusnexo: 0x007831FF => clear one frame - // thegrid: 0x008831FF => clear one frame - // thegrid: 0x0079FFFF => clear entire frame buffer at 51=0 then 51=00800000, only seen at initial tests in thegrid - uint32_t addr = frame_addr_from_phys_addr(m_zeusbase[0x51]); - uint32_t numBytes = (m_zeusbase[0x50] & 0xffff) + 1; - numBytes *= 0x40; - if (m_zeusbase[0x50] & 0x10000) { - addr = 0x0; - numBytes = WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 8; - //printf("Clearing buffer: numBytes: %08X addr: %08X reg50: %08X\n", numBytes, addr, m_zeusbase[0x50]); - } - if (logit) - logerror(" -- Clearing buffer: numBytes: %08X addr: %08X reg51: %08X", numBytes, addr, m_zeusbase[0x51]); - memset(&m_frameColor[addr], m_fill_color, numBytes); - memset(&m_frameDepth[addr], m_fill_depth, numBytes); - } - break; - case 0x9: - frame_write(); - break; - default: - logerror("unknown code = %x offset = %x", code, offset); - break; + switch (code) { + case 0: + // NOP + break; + case 1: + // SGRAM Special Mode Register Write + if (m_zeusbase[0x51] == 0x00200000) { + // SGRAM Mask Register + if ((m_zeusbase[0x58] & m_zeusbase[0x59] & m_zeusbase[0x5a]) != 0xffffffff) + logerror("zeus2_register_update: Warning! Mask Register not equal to 0xffffffff\n"); } + if (m_zeusbase[0x51] == 0x00400000) { + // SGRAM Color Register + m_fill_color = m_zeusbase[0x58] & 0xffffff; + m_fill_depth = ((m_zeusbase[0x5a] & 0xffff) << 8) | (m_zeusbase[0x58] >> 24); + //m_fill_depth = 0; + if (m_zeusbase[0x58] != m_zeusbase[0x59]) + logerror("zeus2_register_update: Warning! Different fill colors are set.\n"); + if (logit) + logerror(" -- Setting fill color = %06X depth = %06X ", m_fill_color, m_fill_depth); + } + break; + case 0x2: + frame_read(); + break; + case 0x8: + { + // Fast clear + // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame + // crusnexo: 0x007831FF => clear one frame + // thegrid: 0x008831FF => clear one frame + // thegrid: 0x0079FFFF => clear entire frame buffer at 51=0 then 51=00800000, only seen at initial tests in thegrid + uint32_t addr = frame_addr_from_phys_addr(m_zeusbase[0x51]); + uint32_t numBytes = (m_zeusbase[0x50] & 0xffff) + 1; + numBytes *= 0x40; + if (m_zeusbase[0x50] & 0x10000) { + addr = 0x0; + numBytes = WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 8; + printf("Clearing buffer: numBytes: %08X addr: %08X reg50: %08X\n", numBytes, addr, m_zeusbase[0x50]); + } + if (logit) + logerror(" -- Clearing buffer: numBytes: %08X addr: %08X reg51: %08X", numBytes, addr, m_zeusbase[0x51]); + memset(&m_frameColor[addr], m_fill_color, numBytes); + memset(&m_frameDepth[addr], m_fill_depth, numBytes); } break; + case 0x9: + { + // Fast fill from local regs + uint32_t numDWords = (m_zeusbase[0x50] & 0xffff) + 1; + //numDWords *= 0x8; + //printf("Filling buffer: numDWords: %08X addr: %08X reg50: %08X reg5e: %08X\n", numDWords, m_zeusbase[0x51], m_zeusbase[0x50], m_zeusbase[0x5e]); + for (int dword = 0; dword < numDWords; dword++) + frame_write(); + } + break; + default: + logerror("unknown code = %x offset = %x", code, offset); + break; + } + } + break; // 0x60, 0x61, 0x62 Translation matrix, set using fifo command - case 0x63: - if (logit) - logerror("\tMAC Trans3 HSR Correction Factor = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x60: case 0x61: case 0x62: case 0x63: + zeus_trans[offset & 3] = convert_float(m_zeusbase[offset]); + if (logit) + logerror("\tMAC Trans%d = %8.2f", offset & 3, reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x64: - if (logit) - logerror("\tMAC Offset"); - break; + case 0x64: + if (logit) + logerror("\tMAC Offset"); + break; - case 0x65: - if (logit) - logerror("\tMAC Offset"); - break; + case 0x65: + if (logit) + logerror("\tMAC Offset"); + break; - case 0x66: - if (logit) - logerror("\tMultiply Offset"); - break; + case 0x66: + if (logit) + logerror("\tMultiply Offset"); + break; - case 0x67: - if (logit) - logerror("\tMath MAC Setup"); - break; + case 0x67: + if (logit) + logerror("\tMath MAC Setup"); + break; - case 0x68: - if (logit) - logerror("\tALU Float Offset"); - break; + case 0x68: + if (logit) + logerror("\tALU Float Offset"); + break; - case 0x6A: - if (logit) - logerror("\tALU RegC X_OFF = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x6A: + if (logit) + logerror("\tALU RegC X_OFF = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x6B: - if (logit) - logerror("\tALU RegD Y_OFF = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x6B: + if (logit) + logerror("\tALU RegD Y_OFF = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x6c: - if (logit) - logerror("\tALU Inv Offset"); - break; + case 0x6c: + if (logit) + logerror("\tALU Inv Offset"); + break; - case 0x6f: - if (logit) - logerror("\tLight Table Setup"); - break; + case 0x6f: + if (logit) + logerror("\tLight Table Setup"); + break; - case 0x76: - if (logit) - logerror("\tMath Comp Reg0 XClip = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x76: + if (logit) + logerror("\tMath Comp Reg0 XClip = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x77: - if (logit) - logerror("\tMath Comp Reg1 YClip = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x77: + if (logit) + logerror("\tMath Comp Reg1 YClip = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x78: - if (logit) - logerror("\tMath Comp Reg2 ZClip = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x78: + if (logit) + logerror("\tMath Comp Reg2 ZClip = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x79: - if (logit) - logerror("\tMath Comp Reg3 YRange = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); - break; + case 0x79: + if (logit) + logerror("\tMath Comp Reg3 YRange = %8.2f", reinterpret_cast<float&>(m_zeusbase[offset])); + break; - case 0x7a: - if (logit) - logerror("\tMath Conditional Branch Setup"); - break; + case 0x7a: + if (logit) + logerror("\tMath Conditional Branch Setup"); + break; - case 0x7c: - if (logit) - logerror("\tMath Compare Setup 1"); - break; + case 0x7c: + if (logit) + logerror("\tMath Compare Setup 1"); + break; - case 0x7D: - if (logit) - logerror("\tMath FIFO AF / AE Input FIFO AF / AE"); - break; + case 0x7D: + if (logit) + logerror("\tMath FIFO AF / AE Input FIFO AF / AE"); + break; - case 0x7f: - if (logit) - logerror("\tMath Setup Reg"); - break; + case 0x7f: + if (logit) + logerror("\tMath Setup Reg"); + break; } if (logit) @@ -1003,7 +1015,8 @@ if (subregdata_count[which] < 256) break; case 0x15: - m_zbufmin = int32_t((value & 0xffffff) << 8) >> 8; + //m_zbufmin = int32_t((value & 0xffffff) << 8) >> 8; + m_zbufmin = value & 0xffffff; if (logit) logerror("\t(R%02X) = %d ZBuf Min", which, m_zbufmin / 4096.0f); break; @@ -1071,7 +1084,7 @@ bool zeus2_device::zeus2_fifo_process(const uint32_t *data, int numwords) case 0x08: if (numwords < 14) return false; - zeus2_register32_w(0x63, data[1], log_fifo); + zeus_trans[3] = convert_float(data[1]); dataoffs = 1; /* 0x07: set matrix and point (crusnexo) */ @@ -1091,20 +1104,18 @@ bool zeus2_device::zeus2_fifo_process(const uint32_t *data, int numwords) zeus_matrix[2][2] = convert_float(data[dataoffs + 9]); /* extract the translation point from the raw data */ - zeus_point[0] = convert_float(data[dataoffs + 10]); - zeus_point[1] = convert_float(data[dataoffs + 11]); - zeus_point[2] = convert_float(data[dataoffs + 12]); + zeus_trans[0] = convert_float(data[dataoffs + 10]); + zeus_trans[1] = convert_float(data[dataoffs + 11]); + zeus_trans[2] = convert_float(data[dataoffs + 12]); if (log_fifo) { log_fifo_command(data, numwords, "\n"); - logerror("\t\tmatrix ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f )\n\t\tvector %8.2f %8.2f %8.5f\n", + logerror("\t\tmatrix ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f )\n\t\ttrans_vector %8.2f %8.2f %8.5f %8.2f\n", (double) zeus_matrix[0][0], (double) zeus_matrix[0][1], (double) zeus_matrix[0][2], (double) zeus_matrix[1][0], (double) zeus_matrix[1][1], (double) zeus_matrix[1][2], (double) zeus_matrix[2][0], (double) zeus_matrix[2][1], (double) zeus_matrix[2][2], - (double) zeus_point[0], - (double) zeus_point[1], - (double) zeus_point[2]); + (double) zeus_trans[0], (double) zeus_trans[1], (double) zeus_trans[2], (double)zeus_trans[3]); } break; @@ -1118,17 +1129,15 @@ bool zeus2_device::zeus2_fifo_process(const uint32_t *data, int numwords) return false; /* extract the translation point from the raw data */ - zeus_point[0] = convert_float(data[1]); - zeus_point[1] = convert_float(data[2]); - zeus_point[2] = convert_float(data[3]); + zeus_trans[0] = convert_float(data[1]); + zeus_trans[1] = convert_float(data[2]); + zeus_trans[2] = convert_float(data[3]); if (log_fifo) { log_fifo_command(data, numwords, "\n"); - logerror("\t\tvector %8.2f %8.2f %8.5f\n", - (double) zeus_point[0], - (double) zeus_point[1], - (double) zeus_point[2]); + logerror("\t\ttrans_vector %8.2f %8.2f %8.2f %8.2f\n", + (double)zeus_trans[0], (double)zeus_trans[1], (double)zeus_trans[2], (double)zeus_trans[3]); } break; @@ -1150,16 +1159,14 @@ bool zeus2_device::zeus2_fifo_process(const uint32_t *data, int numwords) return false; if (log_fifo) { - log_fifo_command(data, numwords, " -- unknown control + happens after clear screen\n"); - logerror("\t\tvector2 %8.2f %8.2f %8.5f\n", - (double) convert_float(data[1]), - (double) convert_float(data[2]), - (double) convert_float(data[3])); - /* extract the translation point from the raw data */ - zeus_point2[0] = convert_float(data[1]); - zeus_point2[1] = convert_float(data[2]); - zeus_point2[2] = convert_float(data[3]); + zeus_light[0] = convert_float(data[1]); + zeus_light[1] = convert_float(data[2]); + zeus_light[2] = convert_float(data[3]); + log_fifo_command(data, numwords, " -- Set light vector\n"); + logerror("\t\tlight_vector %8.2f %8.2f %8.2f\n", + (double)zeus_light[0], (double)zeus_light[1], (double)zeus_light[2]); + } break; @@ -1206,6 +1213,7 @@ bool zeus2_device::zeus2_fifo_process(const uint32_t *data, int numwords) case 0x25: case 0x31: case 0x32: + poly->wait("REND_WAIT"); if (log_fifo) log_fifo_command(data, numwords, " sync? \n"); break; @@ -1252,7 +1260,7 @@ bool zeus2_device::zeus2_fifo_process(const uint32_t *data, int numwords) void zeus2_device::zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit) { - uint32_t databuffer[32]; + uint32_t databuffer[512]; int databufcount = 0; int model_done = false; uint32_t texdata = 0; @@ -1286,7 +1294,7 @@ void zeus2_device::zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit cmd = databuffer[0] >> 24; subCmd = (databuffer[1] >> 24) & 0xfc; - if ((cmd == 0x38 && subCmd != 0x38) || (cmd == 0x2d)) { + if ((cmd == 0x38) || (cmd == 0x2d)) { countneeded = zeus_quad_size; } if (databufcount == countneeded) @@ -1294,8 +1302,6 @@ void zeus2_device::zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit /* handle logging of the command */ if (logit) { - //if ((cmd == 0x38) || (cmd == 0x2d)) - // log_render_info(texdata); if (cmd != 0x00 || (cmd == 0x00 && curoffs == count)) { logerror("\t"); for (int offs = 0; offs < databufcount; offs++) @@ -1312,37 +1318,24 @@ void zeus2_device::zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit logerror(" end cmd 00\n"); case 0x21: /* thegrid */ case 0x22: /* crusnexo */ - if (((databuffer[0] >> 16) & 0xff) == 0x9b) - { - texdata = databuffer[1]; - if (logit) - logerror("texdata\n"); - } - else if (1 && ((databuffer[0] >> 16) & 0xff) == 0x98) - { - texdata = databuffer[1]; - if (logit) - logerror("98_texdata\n"); - } - else if (1 && ((databuffer[0] >> 16) & 0xff) == 0x99) - { - texdata = databuffer[1]; - if (logit) - logerror("99_texdata\n"); - } - else if (1 && ((databuffer[0] >> 16) & 0xff) == 0x9a) + { + int regSel = (databuffer[0] >> 16) & 0xff; + if ((regSel >= 0x98) && (regSel <= 0x9b)) { texdata = databuffer[1]; + m_texmodeReg = regSel; if (logit) - logerror("9a_texdata\n"); + logerror("texdata @%02X\n", regSel); } else if (logit) logerror("unknown offset %08X %08X\n", databuffer[0], databuffer[1]); + } break; case 0x31: /* thegrid */ + poly->wait("REND_WAIT"); if (logit) - logerror("sync?\n"); + logerror("wait for renderer not active\n"); break; case 0x29: // atlantis @@ -1358,45 +1351,15 @@ void zeus2_device::zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit break; case 0x38: /* crusnexo/thegrid */ - if (subCmd == 0x38) { - // Direct commands from waveram buffer - //uint32_t cmdData[2]; - //for (int subIndex = 0; subIndex < 2; ++subIndex) { - // uint32_t offset = (databuffer[subIndex] & 0xff) * 6; - // //printf("directRead curoffs: 0x%X\n", curoffs); - // for (int cmdIndex = 0; cmdIndex < 3; ++cmdIndex) { - // cmdData[0] = m_directCmd[offset + cmdIndex * 2 + 0]; - // cmdData[1] = m_directCmd[offset + cmdIndex * 2 + 1]; - // if (curoffs < 0x40) - // printf("directRead curoffs: 0x%X cmdData %08X %08X\n", curoffs, cmdData[0], cmdData[1]); - // if (cmdData[0] != 0 && cmdData[1] != 0) { - // // Error check - // if (cmdData[0] != 0x58 && cmdData[0] != 0x5A) { - // if (curoffs < 0x20) - // printf("case38 error curoffs: 0x%X cmdData %08X %08X\n", curoffs, cmdData[0], cmdData[1]); - // } - // else { - // zeus2_register32_w(cmdData[0] & 0x7f, cmdData[1], logit); - // } - // } - // } - //} - //void *palbase = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]); - //uint8_t texel = databuffer[0]; - //uint32_t color = WAVERAM_READ16(palbase, texel); - //m_frameDepth[m_renderAddr] = 0; - //m_frameColor[m_renderAddr++] = conv_rgb555_to_rgb32(color); - //texel = databuffer[1]; - //color = WAVERAM_READ16(palbase, texel); - //m_frameDepth[m_renderAddr] = 0; - //m_frameColor[m_renderAddr++] = conv_rgb555_to_rgb32(color); - //m_frameDepth[m_renderAddr] = 0; - //m_frameColor[m_renderAddr++] = databuffer[0] & 0x00ffffff; - //m_frameDepth[m_renderAddr] = 0; - //m_frameColor[m_renderAddr++] = databuffer[1] & 0x00ffffff; - //if (logit) - // if ((curoffs + 1) % 16 == 0) - // logerror("\n"); + if (m_system==THEGRID && m_curUCodeSrc==0x00000343) { + if (logit) + logerror("direct write [57]=%08X [51]==%08X\n", m_zeusbase[0x57], m_zeusbase[0x51]); + // Direct write to frame buffer + for (int subIndex = 0; subIndex < zeus_quad_size / 2; ++subIndex) { + m_zeusbase[0x5a] = databuffer[subIndex * 2 + 1] & 0xffffff; + m_zeusbase[0x58] = databuffer[subIndex * 2 + 0] & 0xffffff; + frame_write(); + } } else { poly->zeus2_draw_quad(databuffer, texdata, logit); @@ -1434,12 +1397,9 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat z2_poly_vertex clipvert[8]; z2_poly_vertex vert[4]; // float uscale, vscale; - float maxy, maxx; // int val1, val2, texwshift; int numverts; int i; - // int16_t normal[3]; - // int32_t rotnormal[3]; if (logit) { m_state->logerror("quad %d", m_state->zeus_quad_size); @@ -1463,48 +1423,30 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat //if (machine().input().code_pressed(KEYCODE_I) && (texdata & 0xffff) == 0x119) return; //if (machine().input().code_pressed(KEYCODE_O) && (texdata & 0xffff) == 0x119) return; //if (machine().input().code_pressed(KEYCODE_L) && (texdata & 0x100)) return; + //if (m_state->m_texmodeReg != 0x9b) return; + + // PZr = (PZ * M22) + (PY * M21) + (PX * M20) + 0 + // AZp = (AZ * M22) + (AY * M21) + (AX * M20) + TZ + // AYp = (AZ * M12) + (AY * M11) + (AX * M10) + TY + // AXp = (AZ * M02) + (AY * M01) + (AX * M00) + TX + + // Fast HSR Removal + if (1) + { + float PZr; + + int8_t normal[3]; + normal[0] = databuffer[0] >> 0; + normal[1] = databuffer[0] >> 8; + normal[2] = databuffer[0] >> 16; + + PZr = normal[0] * m_state->zeus_matrix[2][0] + normal[1] * m_state->zeus_matrix[2][1] + normal[2] * m_state->zeus_matrix[2][2] + m_state->zeus_trans[3]; + + //m_state->logerror("norm: %i %i %i PZr: %f\n", normal[0], normal[1], normal[2], PZr); + if (PZr >= 0) + return; + } - /* - 0 38800000 - 1 x2 | x1 - 2 v1 | u1 - 3 y2 | y1 - 4 v2 | u2 - 5 z2 | z1 - 6 v3 | u3 - 7 v4 | u4 - 8 ??? - 9 x4 | x3 - 10 y4 | y3 - 11 z4 | z3 - - In memory: - +0 = ??? - +1 = set via $05410000/value - +2 = x1 - +3 = y1 - +4 = z1 - +5 = x2 - +6 = y2 - +7 = z2 - +8 = x3 - +9 = y3 - +10= z3 - +11= x4 - +12= y4 - +13= z4 - +14= uv1 - +15= uv2 - +16= uv3 - +17= uv4 - +18= set via $05200000/$05000000 | (value << 10) (uvoffset?) - +19= ??? - - - 38810000 00000000 00C7|FF38 FF5E|FF5E 15400154 11400114 00000000 00000000 FF38|00C7 00A3|00A3 -- quad - xxxx|xxxx yyyy|yyyy xxxx|xxxx yyyy|yyyy - */ - // Altantis rendermode: 0x024004 startup, then 0x020202, then 0x021E0E /* extract raw x,y,z */ if (m_state->m_atlantis) { // Atlantis quad 14 @@ -1577,36 +1519,12 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat unknownFloat[2] = m_state->convert_float(databuffer[12]); unknownFloat[3] = m_state->convert_float(databuffer[13]); } - /* - vert[0].x = (int16_t)databuffer[1]; - vert[0].y = (int16_t)databuffer[3]; - vert[0].p[0] = (int16_t)databuffer[5]; - vert[0].p[1] = (uint16_t)databuffer[2]; - vert[0].p[2] = (uint16_t)(databuffer[2] >> 16); - - vert[1].x = (int16_t)(databuffer[1] >> 16); - vert[1].y = (int16_t)(databuffer[3] >> 16); - vert[1].p[0] = (int16_t)(databuffer[5] >> 16); - vert[1].p[1] = (uint16_t)databuffer[4]; - vert[1].p[2] = (uint16_t)(databuffer[4] >> 16); - - vert[2].x = (int16_t)databuffer[9]; - vert[2].y = (int16_t)databuffer[10]; - vert[2].p[0] = (int16_t)databuffer[11]; - vert[2].p[1] = (uint16_t)databuffer[6]; - vert[2].p[2] = (uint16_t)(databuffer[6] >> 16); - - vert[3].x = (int16_t)(databuffer[9] >> 16); - vert[3].y = (int16_t)(databuffer[10] >> 16); - vert[3].p[0] = (int16_t)(databuffer[11] >> 16); - vert[3].p[1] = (uint16_t)databuffer[7]; - vert[3].p[2] = (uint16_t)(databuffer[7] >> 16); - */ int logextra = 1; int intScale = m_state->m_zeusbase[0x66] - 0x8e; float fScale = pow(2.0f, intScale); + for (i = 0; i < 4; i++) { float x = vert[i].x; @@ -1619,50 +1537,26 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat } #if PRINT_TEX_INFO if (logit && i == 0) { - m_state->check_tex(texdata, z, m_state->zeus_matrix[2][2], m_state->zeus_point[2]); + m_state->check_tex(texdata, z, m_state->zeus_matrix[2][2], m_state->zeus_trans[2]); } #endif - vert[i].x = x * m_state->zeus_matrix[0][0] + y * m_state->zeus_matrix[0][1] + z * m_state->zeus_matrix[0][2]; - vert[i].y = x * m_state->zeus_matrix[1][0] + y * m_state->zeus_matrix[1][1] + z * m_state->zeus_matrix[1][2]; + vert[i].x = x * m_state->zeus_matrix[0][0] + y * m_state->zeus_matrix[0][1] + z * m_state->zeus_matrix[0][2]; + vert[i].y = x * m_state->zeus_matrix[1][0] + y * m_state->zeus_matrix[1][1] + z * m_state->zeus_matrix[1][2]; vert[i].p[0] = x * m_state->zeus_matrix[2][0] + y * m_state->zeus_matrix[2][1] + z * m_state->zeus_matrix[2][2]; - if (1) { - vert[i].x += m_state->zeus_point[0]; - vert[i].y += m_state->zeus_point[1]; - vert[i].p[0] += m_state->zeus_point[2]; - } + vert[i].x += m_state->zeus_trans[0]; + vert[i].y += m_state->zeus_trans[1]; + vert[i].p[0] += m_state->zeus_trans[2]; - if (0) { - int shift; - shift = 1024 >> m_state->m_zeusbase[0x6c]; - vert[i].p[0] += shift; - } + // Clamp to zero if negative + if (vert[i].p[0] < 0) + vert[i].p[0] = 0.0f; + //vert[i].p[1] += ((texdata >> 8) & 0x1) ? 1.0f : 0.0f; vert[i].p[2] += (texdata >> 16); vert[i].p[1] *= 256.0f; vert[i].p[2] *= 256.0f; - // back face cull using polygon normal and first vertex - if (0 && i == 0) - { - float rotnormal[3]; - - int8_t normal[3]; - normal[0] = databuffer[0] >> 0; - normal[1] = databuffer[0] >> 8; - normal[2] = databuffer[0] >> 16; - //m_state->logerror("norm: %i %i %i\n", normal[0], normal[1], normal[2]); - if (normal[2] != -128) { - rotnormal[0] = normal[0] * m_state->zeus_matrix[0][0] + normal[1] * m_state->zeus_matrix[0][1] + normal[2] * m_state->zeus_matrix[0][2]; - rotnormal[1] = normal[0] * m_state->zeus_matrix[1][0] + normal[1] * m_state->zeus_matrix[1][1] + normal[2] * m_state->zeus_matrix[1][2]; - rotnormal[2] = normal[0] * m_state->zeus_matrix[2][0] + normal[1] * m_state->zeus_matrix[2][1] + normal[2] * m_state->zeus_matrix[2][2]; - - float dot = rotnormal[0] * vert[0].x + rotnormal[1] * vert[0].y + rotnormal[2] * vert[0].p[0]; - - if (dot >= 0) - return; - } - } if (logextra & logit) @@ -1677,143 +1571,85 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat unknown[0], unknown[1], unknown[2], unknown[3], unknown[4], unknown[5], unknown[6], unknown[7], unknownFloat[0], unknownFloat[1], unknownFloat[2], unknownFloat[3]); } - //bool enable_perspective = true; // !(m_state->m_renderRegs[0x14] & 0x2); - //float clipVal = enable_perspective ? 1.0f / 512.0f / 4.0f : 0.0f; - float clipVal = m_state->m_zbufmin / 4096.0f; - if (1) { - numverts = this->zclip_if_less(4, &vert[0], &clipvert[0], 4, clipVal); - if (numverts < 3) - return; - } - else { - numverts = 4; - clipvert[0] = vert[0]; - clipvert[1] = vert[1]; - clipvert[2] = vert[2]; - clipvert[3] = vert[3]; - } + float xOrigin = reinterpret_cast<float&>(m_state->m_zeusbase[0x6a]); float yOrigin = reinterpret_cast<float&>(m_state->m_zeusbase[0x6b]); - float oozBase = (m_state->m_atlantis) ? 1024.0f : (m_state->m_system == m_state->THEGRID) ? 512.0f : 512.0f; - //oozBase = 1 << m_state->m_zeusbase[0x6c]; - maxx = maxy = -1000.0f; - for (i = 0; i < numverts; i++) - { - if (0 && (m_state->m_renderRegs[0x14] & 0x1)) { - clipvert[i].p[0] += reinterpret_cast<float&>(m_state->m_zeusbase[0x63]); - } - // mwskinsa has R14=0x40a1 for tips box which has z=0 - //if (!(m_state->m_renderRegs[0x14] & 0x1)) { - //if (enable_perspective) { - // 412.0f here works for crusnexo - // 1024.0f works for mwskinsa - float ooz = oozBase / (clipvert[i].p[0] + (1024 >> m_state->m_zeusbase[0x6c])); - //ooz = oozBase / (oozBase - clipvert[i].p[0]); - //float ooz = 1024.0f / clipvert[i].p[0]; - //float ooz = float(1 << m_state->m_zeusbase[0x6c]) / clipvert[i].p[0]; - clipvert[i].x *= ooz; - clipvert[i].y *= ooz; - //} + // crusn seems to use a different z scale + float zRound = (m_state->m_system == m_state->CRUSNEXO) ? 2.0f : 0.5f; + float oozBase = 1 << m_state->m_zeusbase[0x6c]; + //float maxy, maxx; + //maxx = maxy = -1000.0f; + for (i = 0; i < 4; i++) + { + float ooz = oozBase / (vert[i].p[0] + zRound); if (1) { - //clipvert[i].x += 256.5f / 1.0f; - //clipvert[i].y += 200.5f / 1.0f; - clipvert[i].x += xOrigin; - clipvert[i].y += yOrigin; - //clipvert[i].p[0] += reinterpret_cast<float&>(m_state->m_zeusbase[0x63]); - //clipvert[i].p[0] *= -1.0f; + //vert[i].p[0] += reinterpret_cast<float&>(m_state->m_zeusbase[0x63]); + vert[i].x *= ooz; + vert[i].y *= ooz; + //vert[i].p[0] = ooz; } + vert[i].x += xOrigin; + vert[i].y += yOrigin; + //clipvert[i].p[0] *= 65536.0f * 16.0f; - clipvert[i].p[0] *= 4096.0f; + vert[i].p[0] *= 4096.0f * 2.0f; // 12.12 - maxx = std::max(maxx, clipvert[i].x); - maxy = std::max(maxy, clipvert[i].y); + //maxx = std::max(maxx, clipvert[i].x); + //maxy = std::max(maxy, clipvert[i].y); if (logextra & logit) - m_state->logerror("\t\t\tTranslated=(%f,%f, %f) scale = %f\n", (double)clipvert[i].x, (double)clipvert[i].y, (double)clipvert[i].p[0], ooz); + m_state->logerror("\t\t\tTranslated=(%f,%f, %f) scale = %f\n", (double)vert[i].x, (double)vert[i].y, (double)vert[i].p[0], ooz); } - for (i = 0; i < numverts; i++) - { - if (clipvert[i].x == maxx) - clipvert[i].x += 0.0005f; - if (clipvert[i].y == maxy) - clipvert[i].y += 0.0005f; + // Slow HSR + // ((AYs - BYs) * (BXs - CXs)) - ((AXs - BXs) * (BYs - CYs)) + if (1) { + float slowHSR = ((vert[0].y - vert[1].y) * (vert[1].x - vert[2].x) - (vert[0].x - vert[1].x) * (vert[1].y - vert[2].y)); + if (slowHSR >= 0) + return; } - zeus2_poly_extra_data& extra = this->object_data_alloc(); - int texmode = texdata & 0xffff; - // 0x014d == atlantis initial screen and scoreboard background - //if (texmode != 0x014D) return; - // Just a guess but seems to work - //int texTmp = (texmode & 0x20) ? 0x10 : 0x20; - //extra.texwidth = texTmp << ((texmode >> 2) & 3); - extra.texwidth = 0x20 << ((texmode >> 2) & 3); - //if (texmode & 0x80) extra.texwidth <<= 1; - //if (m_state->m_palSize == 16) extra.texwidth *= 2; - //switch (texmode) + //for (i = 0; i < numverts; i++) //{ - //case 0x14d: // atlantis - //case 0x18e: // atlantis - //case 0x01d: /* crusnexo: RHS of score bar */ - //case 0x05d: /* crusnexo: background, road */ - //case 0x0dd: /* crusnexo: license plate letters */ - //case 0x11d: /* crusnexo: LHS of score bar */ - //case 0x15d: /* crusnexo */ - //case 0x85d: /* crusnexo */ - //case 0x95d: /* crusnexo */ - //case 0xc1d: /* crusnexo */ - //case 0xc5d: /* crusnexo */ - // extra.texwidth = 256; - // break; - - //case 0x18a: // atlantis - //case 0x059: /* crusnexo */ - //case 0x0d9: /* crusnexo */ - //case 0x119: /* crusnexo: license plates */ - //case 0x159: /* crusnexo */ - // extra.texwidth = 128; - // break; - - //case 0x055: /* crusnexo */ - //case 0x145: // atlantis - //case 0x155: /* crusnexo */ - // extra.texwidth = 64; - // break; - - //case 0x000: // thegrid guess - //case 0x140: // atlantis - //case 0x141: // atlantis - // extra.texwidth = 32; - // break; - //case 0x120: // thegrid "LOADING" - // extra.texwidth = 16; - - //default: - //{ - // static uint8_t hits[0x10000]; - // if (!hits[(texdata & 0xffff)]) - // { - // hits[(texdata & 0xffff)] = 1; - // printf("texMode = %04X\n", (texdata & 0xffff)); - // } - // break; - //} + // if (clipvert[i].x == maxx) + // clipvert[i].x += 0.0005f; + // if (clipvert[i].y == maxy) + // clipvert[i].y += 0.0005f; //} + zeus2_poly_extra_data& extra = this->object_data_alloc(); + + // Z clip + extra.depth_min_enable = true;// !(m_state->m_renderRegs[0x14] & 0x000040); + if (1 && extra.depth_min_enable) { + float clipVal = m_state->m_zbufmin / 4096.0f; + numverts = this->zclip_if_less(4, &vert[0], &clipvert[0], 4, clipVal); + if (numverts < 4) + return; + } + else { + numverts = 4; + clipvert[0] = vert[0]; + clipvert[1] = vert[1]; + clipvert[2] = vert[2]; + clipvert[3] = vert[3]; + } + + int texmode = texdata & 0xffff; + extra.texwidth = 0x20 << ((texmode >> 2) & 3); extra.solidcolor = 0;//m_zeusbase[0x00] & 0x7fff; extra.zbufmin = m_state->m_zbufmin; - extra.alpha = 0;//m_zeusbase[0x4e]; extra.transcolor = 0; // (texmode & 0x100) ? 0 : 0x100; extra.texbase = WAVERAM_BLOCK0_EXT(m_state->zeus_texbase); - //extra.palbase = m_state->waveram0_ptr_from_expanded_addr(m_state->m_zeusbase[0x41]); - //extra.depth_test_enable = !(m_state->m_renderRegs[0x40] & 0x020000); - // crusnexo text is R14=0x4062 extra.depth_test_enable = !(m_state->m_renderRegs[0x14] & 0x000020); - extra.depth_min_enable = false; // !(m_state->m_renderRegs[0x14] & 0x000040); - //extra.depth_test_enable = !(m_state->m_renderRegs[0x40] & 0x000002); - //extra.depth_test_enable = true; // (texmode & 0x0010); - extra.depth_write_enable = true; + extra.depth_write_enable = true; // (m_state->m_renderRegs[0x14] & 0x004000); + extra.depth_clear_enable = false; // (m_state->m_renderRegs[0x14] & 0x001000); + // 021e0e = blend with texture alpha, 020202 blend src / dst alpha + extra.blend_enable = ((m_state->m_renderRegs[0x40] == 0x020202) || (m_state->m_renderRegs[0x40] == 0x021e0e)); + extra.srcAlpha = m_state->m_renderRegs[0x0c]; + extra.dstAlpha = m_state->m_renderRegs[0x0d]; + extra.texture_alpha = false; switch (texmode & 0x3) { case 0: extra.get_texel = m_state->get_texel_4bit_2x2; @@ -1823,12 +1659,14 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat extra.get_texel = m_state->get_texel_8bit_4x2; break; case 2: - if (texmode & 0x80) { + // Seems to select texture with embedded alpha + if (1) { // Texel , Alpha extra.get_texel = m_state->get_texel_8bit_2x2_alpha; - } - else { - extra.get_texel = m_state->get_texel_8bit_2x2; + extra.texture_alpha = true; + extra.get_alpha = m_state->get_alpha_8bit_2x2_alpha; + extra.depth_test_enable = false; + extra.depth_write_enable = false; } break; default: @@ -1836,8 +1674,7 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat extra.get_texel = m_state->get_texel_8bit_2x2; break; } - //extra.get_texel = ((texmode & 0x1) == 0) ? m_state->get_texel_alt_4bit : m_state->get_texel_8bit; - //extra.get_texel = m_state->get_texel_alt_4bit; + // Note: Before being converted to the "poly.h" interface, this used to call the polylgcy function // poly_render_quad_fan. The behavior seems to be the same as it once was after a few short // tests, but the (numverts == 5) statement below may actually be a quad fan instead of a 5-sided @@ -1858,7 +1695,7 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat void zeus2_renderer::render_poly_8bit(int32_t scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid) { - int32_t curz = extent.param[0].start; + uint32_t curz = extent.param[0].start; int32_t curu = extent.param[1].start; int32_t curv = extent.param[2].start; // int32_t curi = extent.param[3].start; @@ -1869,9 +1706,17 @@ void zeus2_renderer::render_poly_8bit(int32_t scanline, const extent_t& extent, const void *texbase = object.texbase; //const void *palbase = object.palbase; uint16_t transcolor = object.transcolor; + int32_t srcAlpha = object.srcAlpha; + int32_t dstAlpha = object.dstAlpha; + int texwidth = object.texwidth; int x; + if (object.depth_clear_enable) { + curz = 0x0; + dzdx = 0; + } + uint32_t addr = m_state->frame_addr_from_xy(0, scanline, true); uint32_t *depthptr = &m_state->m_frameDepth[addr]; uint32_t *colorptr = &m_state->m_frameColor[addr]; @@ -1879,34 +1724,121 @@ void zeus2_renderer::render_poly_8bit(int32_t scanline, const extent_t& extent, { bool depth_pass = true; if (object.depth_test_enable) { - if (object.depth_min_enable && curz < object.zbufmin) + if (0 && object.depth_min_enable && curz < object.zbufmin) depth_pass = false; - if (curz < 0 || curz > depthptr[x]) + if (curz > depthptr[x]) depth_pass = false; - else if (object.depth_write_enable) - depthptr[x] = curz; // Should limit to 24 bits } if (depth_pass) { - int u0 = (curu >> 8);// & (texwidth - 1); - int v0 = (curv >> 8);// & 255; + int u0 = (curu >> 8);// &(texwidth - 1); + int v0 = (curv >> 8);// &255; int u1 = (u0 + 1); int v1 = (v0 + 1); - uint8_t texel0 = object.get_texel(texbase, v0, u0, texwidth); - //if (texel0 == transcolor) - // continue; - uint8_t texel1 = object.get_texel(texbase, v0, u1, texwidth); - uint8_t texel2 = object.get_texel(texbase, v1, u0, texwidth); - uint8_t texel3 = object.get_texel(texbase, v1, u1, texwidth); - //if (texel0 != transcolor) - if ((texel0 != transcolor) && (texel1 != transcolor) && (texel2 != transcolor) && (texel3 != transcolor)) - //if (1) - { - uint32_t color0 = m_state->m_pal_table[texel0]; - uint32_t color1 = m_state->m_pal_table[texel1]; - uint32_t color2 = m_state->m_pal_table[texel2]; - uint32_t color3 = m_state->m_pal_table[texel3]; - rgb_t filtered = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv); - colorptr[x] = filtered; + // Rendering for textures with embedded alpha + if (object.texture_alpha) { + // To bilinear filter or not to bilinear filter + if (0) { + // Add rounding + u0 += (curu >> 7) & 1; + v0 += (curv >> 7) & 1; + uint8_t texel0 = object.get_texel(texbase, v0, u0, texwidth); + srcAlpha = object.get_alpha(texbase, v0, u0, texwidth); + if (srcAlpha != 0) { + rgb_t srcColor = m_state->m_pal_table[texel0]; + rgb_t dstColor = colorptr[x]; + dstAlpha = 0xff - srcAlpha; + srcColor.scale8(srcAlpha); + srcColor += dstColor.scale8(dstAlpha); + colorptr[x] = srcColor; + if (object.depth_write_enable) + depthptr[x] = curz; // Should limit to 24 bits + } + } + else { + uint8_t texel0 = object.get_texel(texbase, v0, u0, texwidth); + uint8_t texel1 = object.get_texel(texbase, v0, u1, texwidth); + uint8_t texel2 = object.get_texel(texbase, v1, u0, texwidth); + uint8_t texel3 = object.get_texel(texbase, v1, u1, texwidth); + uint8_t alpha0 = object.get_alpha(texbase, v0, u0, texwidth); + uint8_t alpha1 = object.get_alpha(texbase, v0, u1, texwidth); + uint8_t alpha2 = object.get_alpha(texbase, v1, u0, texwidth); + uint8_t alpha3 = object.get_alpha(texbase, v1, u1, texwidth); + if (1) + { + // Calculate source alpha + //srcAlpha = ((uint32_t)alpha0 + (uint32_t)alpha1 + (uint32_t)alpha2 + (uint32_t)alpha3) >> 2; + uint32_t uFactor = curu & 0xff; + uint32_t vFactor = curv & 0xff; + srcAlpha = ((alpha0 * (256 - uFactor) + alpha1 * (uFactor)) * (256 - vFactor) + (alpha2 * (256 - uFactor) + alpha3 * (uFactor)) * (vFactor)) >> 16; + if (srcAlpha != 0) { + uint32_t color0 = m_state->m_pal_table[texel0]; + uint32_t color1 = m_state->m_pal_table[texel1]; + uint32_t color2 = m_state->m_pal_table[texel2]; + uint32_t color3 = m_state->m_pal_table[texel3]; + rgb_t filtered = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv); + rgb_t dstColor = colorptr[x]; + dstAlpha = 0x100 - srcAlpha; + filtered.scale8(srcAlpha); + filtered += dstColor.scale8(dstAlpha); + colorptr[x] = filtered; + if (object.depth_write_enable) + depthptr[x] = curz; // Should limit to 24 bits + } + } + } + // Rendering for textures with no transparent color + } else if (1 || transcolor == 0x100) { + uint8_t texel0 = object.get_texel(texbase, v0, u0, texwidth); + uint8_t texel1 = object.get_texel(texbase, v0, u1, texwidth); + uint8_t texel2 = object.get_texel(texbase, v1, u0, texwidth); + uint8_t texel3 = object.get_texel(texbase, v1, u1, texwidth); + if ((texel0 != transcolor) && (texel1 != transcolor) && (texel2 != transcolor) && (texel3 != transcolor)) + //if (1) + { + uint32_t color0 = m_state->m_pal_table[texel0]; + uint32_t color1 = m_state->m_pal_table[texel1]; + uint32_t color2 = m_state->m_pal_table[texel2]; + uint32_t color3 = m_state->m_pal_table[texel3]; + rgb_t srcColor = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv); + if (object.blend_enable) { + // Need to check if this is correct or use incoming dstAlpha + //dstAlpha = 0x100 - srcAlpha; + + // If src alpha is 256 don't blend + if (1 || srcAlpha != 0x100) { + rgb_t dstColor = colorptr[x]; + if (srcAlpha != 0x100) + srcColor.scale8(srcAlpha); + if (dstAlpha == 0x100) + srcColor += dstColor; + else + srcColor += dstColor.scale8(dstAlpha); + } + // If src alpha is 0 don't write + if (srcAlpha != 0x00) { + colorptr[x] = srcColor; + if (object.depth_write_enable) + depthptr[x] = curz; // Should limit to 24 bits + } + } + else { + colorptr[x] = srcColor; + if (object.depth_write_enable) + depthptr[x] = curz; // Should limit to 24 bits + } + } + // Rendering for textures with transparent color + //} else { + // // Add rounding + // u0 += (curu >> 7) & 1; + // v0 += (curv >> 7) & 1; + // uint8_t texel0 = object.get_texel(texbase, v0, u0, texwidth); + // if (texel0 != transcolor) { + // uint32_t color0 = m_state->m_pal_table[texel0]; + // colorptr[x] = color0; + // if (object.depth_write_enable) + // depthptr[x] = curz; // Should limit to 24 bits + // } } } curz += dzdx; @@ -1964,15 +1896,18 @@ void zeus2_device::check_tex(uint32_t &texmode, float &zObj, float &zMat, float //infoStream << "pal=0x" << std::setw(4) << std::setfill('0') << (m_curPalTableSrc >> 16) << ", 0x" << std::setw(4) << (m_curPalTableSrc & 0xffff) << " "; infoStream << "pal=0x" << std::setw(8) << std::setfill('0') << m_curPalTableSrc << " "; infoStream << "texdata=" << std::setw(8) << std::hex << texmode << " "; + infoStream << "texReg=" << std::setw(2) << std::hex << m_texmodeReg << " "; infoStream << "(6c)=" << m_zeusbase[0x6c] << " "; - infoStream << "(63)=" << std::dec << reinterpret_cast<float&>(m_zeusbase[0x63]) << " "; - infoStream << "zObj=" << std::dec << zObj << " "; - infoStream << "zMat=" << std::dec << zMat << " "; - infoStream << "zOff=" << std::dec << zOff << " "; + infoStream << "(63)=" << std::setw(6) << std::dec << reinterpret_cast<float&>(m_zeusbase[0x63]) << " "; + //infoStream << "zObj=" << std::setw(6) << std::dec << zObj << " "; + //infoStream << "zMat=" << std::setw(6) << std::dec << zMat << " "; + infoStream << "zOff=" << std::setw(6) << std::dec << zOff << " "; infoStream << "R40=" << std::setw(6) << std::hex << m_renderRegs[0x40] << " "; infoStream << "R14=" << m_renderRegs[0x14] << " "; - infoStream << "R0C=" << std::setw(3) << m_renderRegs[0x0c] << " "; - infoStream << "R0D=" << std::setw(3) << m_renderRegs[0x0d] << " "; + //infoStream << "R0A=" << std::setw(2) << m_renderRegs[0x0a] << " "; + infoStream << "R0B(LC)=" << std::setw(6) << m_renderRegs[0x0b] << " "; + infoStream << "R0C(FGD)=" << std::setw(3) << m_renderRegs[0x0c] << " "; + infoStream << "R0D(BGD)=" << std::setw(3) << m_renderRegs[0x0d] << " "; infoStr += infoStream.str(); infoStr += tex_info(); @@ -2083,25 +2018,74 @@ std::string zeus2_device::tex_info(void) case 0x00011688: retVal = "letter N, s=16, t=4a"; break; case 0x00011768: retVal = "letter G, s=16, t=4a"; break; case 0x00155b40: retVal = "green 1010, s=256, t=8"; break; - case 0x0014db80: retVal = "The Grid logo, s=256, t=8a"; break; - case 0x0014f280: retVal = "Searching fo, s=256, t=8a"; break; - case 0x00150500: retVal = "or, s=64, t=8a"; break; + case 0x0014db80: retVal = "The Grid logo, s=256, t=8alpha"; break; + case 0x0014f280: retVal = "Searching fo, s=256, t=8alpha"; break; + case 0x00150500: retVal = "or, s=64, t=8alpha"; break; + case 0x000c4400: retVal = "P, s=32, t=8alpha"; break; + case 0x000c3ba0: retVal = "U, s=32, t=8alpha"; break; + case 0x000c3c00: retVal = "S, s=32, t=8alpha"; break; + case 0x000c3c60: retVal = "H, s=32, t=8alpha"; break; + case 0x000c39c0: retVal = "T, s=32, t=8alpha"; break; + case 0x000c4c70: retVal = "A, s=32, t=8alpha"; break; + case 0x000c4070: retVal = "R, s=32, t=8alpha"; break; + case 0x000c4460: retVal = "O, s=32, t=8alpha"; break; + case 0x000c47a0: retVal = "E, s=32, t=8alpha"; break; + case 0x000c48f0: retVal = "C, s=32, t=8alpha"; break; + case 0x000c3de0: retVal = "V, s=32, t=8alpha"; break; + case 0x000c4650: retVal = "I, s=32, t=8alpha"; break; + case 0x000c3a20: retVal = "N, s=32, t=8alpha"; break; + case 0x000c4fd0: retVal = "0, s=32, t=8alpha"; break; + case 0x000c4290: retVal = "., s=32, t=8alpha"; break; + case 0x000c4f70: retVal = "2, s=32, t=8alpha"; break; + case 0x000c5030: retVal = "1, s=32, t=8alpha"; break; + case 0x000c3ec0: retVal = "/, s=32, t=8alpha"; break; + case 0x000c4df0: retVal = "6, s=32, t=8alpha"; break; case 0x00150d00: retVal = "System 1, s=128, t=8"; break; case 0x00151360: retVal = "System 2, s=128, t=8"; break; case 0x001519c0: retVal = "System 3, s=128, t=8"; break; case 0x00152020: retVal = "System 4, s=128, t=8"; break; case 0x00152680: retVal = "System 5, s=128, t=8"; break; case 0x00152ce0: retVal = "System 6, s=128, t=8"; break; - case 0x001509c0: retVal = "READY!, s=128, t=8a"; break; - case 0x000c2d10: retVal = "6, s=32, t=8a"; break; - case 0x000c30d0: retVal = "0, s=32, t=8a"; break; - case 0x000c2db0: retVal = "5, s=32, t=8a"; break; - case 0x000c2b30: retVal = "9, s=32, t=8a"; break; - case 0x000c2bd0: retVal = "8, s=32, t=8a"; break; - case 0x000c2c70: retVal = "7, s=32, t=8a"; break; - case 0x000c2e50: retVal = "4, s=32, t=8a"; break; - case 0x000c2ef0: retVal = "3, s=32, t=8a"; break; - case 0x000c2f90: retVal = "2, s=32, t=8a"; break; + case 0x001509c0: retVal = "READY!, s=128, t=8alpha"; break; + case 0x000c2d10: retVal = "6, s=32, t=8alpha"; break; + case 0x000c30d0: retVal = "0, s=32, t=8alpha"; break; + case 0x000c2db0: retVal = "5, s=32, t=8alpha"; break; + case 0x000c2b30: retVal = "9, s=32, t=8alpha"; break; + case 0x000c2bd0: retVal = "8, s=32, t=8alpha"; break; + case 0x000c2c70: retVal = "7, s=32, t=8alpha"; break; + case 0x000c2e50: retVal = "4, s=32, t=8alpha"; break; + case 0x000c2ef0: retVal = "3, s=32, t=8alpha"; break; + case 0x000c2f90: retVal = "2, s=32, t=8alpha"; break; + case 0x000c3030: retVal = "1, s=32, t=8alpha"; break; + case 0x0014fb80: retVal = "Brownish circle, s=64, t=8_4x2"; break; + case 0x0014fd80: retVal = "Midsize Dark circle rainbow edge, s=256, t=8_4x2"; break; + case 0x00150580: retVal = "Dark circle rainbow edge, s=256, t=8_4x2"; break; + case 0x00012fb0: retVal = "Red dots, s=16, t=4_2x2"; break; + case 0x0013b500: retVal = "Flash with purple outer edge, s=128, t=8_alpha"; break; + case 0x001c6220: retVal = "Yellow console?, s=128, t=8_4x2"; break; + case 0x001c58e0: retVal = "White/Red Fabric?, s=128, t=8_4x2"; break; + case 0x001c8b10: retVal = "White Fabric with yellow band LOD0?, s=64, t=8_4x2"; break; + case 0x001c6880: retVal = "White Fabric with yellow band LOD1?, s=128, t=8_4x2"; break; + case 0x001c76e0: retVal = "Chiller face, s=128, t=8_4x2"; break; + case 0x0018cc80: retVal = "Green grid square 10101, s=256, t=8_4x2"; break; + case 0x00187780: retVal = "Left logo The Grid, s=256, t=8_alpha"; break; + case 0x0018a200: retVal = "Right logo the Grid, s=256, t=8_alpha"; break; + case 0x0003cc00: retVal = "CREDITS, s=256, t=8_alpha"; break; + case 0x0003e780: retVal = "INSERT COINS, s=256, t=8_alpha"; break; + case 0x0003fe00: retVal = "White 1, s=32, t=8_alpha"; break; + case 0x0003fbc0: retVal = "White 2, s=64, t=8_alpha"; break; + case 0x0003d580: retVal = "PRESS START, s=256, t=8_alpha"; break; + //case 0x00154740: retVal = "Chiller Face, s=128, t=16rgb"; break; + //case 0x00153340: retVal = "Ike Face, s=128, t=16rgb"; break; + case 0x00154740: retVal = "Just Play, s=256, t=8_4x2"; break; + case 0x00153340: retVal = "Enter Name, s=256, t=8_4x2"; break; + case 0x00130d00: retVal = "Cyrus highlight screen, s=128, t=8_4x2"; break; + case 0x00139700: retVal = "Green Welcome To, s=128, t=4_2x2"; break; + case 0x0012f300: retVal = "More people in stands, s=64, t=8_4x2"; break; + case 0x0012fd00: retVal = "Even more people in stands, s=64, t=8_4x2"; break; + case 0x0003ff20: retVal = "0, s=64, t=8_alpha"; break; + case 0x00130300: retVal = "People in stands, s=64, t=8_4x2"; break; + case 0x0007c8e0: retVal = "Greenish blob, s=64, t=8_alpha"; break; default: retVal = "Unknown"; break; } diff --git a/src/devices/video/zeus2.h b/src/devices/video/zeus2.h index 5912b3518a9..0e1c96df452 100644 --- a/src/devices/video/zeus2.h +++ b/src/devices/video/zeus2.h @@ -21,7 +21,7 @@ #define DUMP_WAVE_RAM 0 #define TRACK_REG_USAGE 0 -#define PRINT_TEX_INFO 0 +#define PRINT_TEX_INFO 1 #define WAVERAM0_WIDTH 1024 #define WAVERAM0_HEIGHT 2048 @@ -42,13 +42,18 @@ struct zeus2_poly_extra_data uint16_t transcolor; uint16_t texwidth; uint16_t color; - uint32_t alpha; + uint32_t srcAlpha; + uint32_t dstAlpha; uint32_t ctrl_word; + bool texture_alpha; bool blend_enable; bool depth_min_enable; bool depth_test_enable; bool depth_write_enable; + bool depth_clear_enable; + uint8_t(*get_texel)(const void *, int, int, int); + uint8_t(*get_alpha)(const void *, int, int, int); }; /************************************* @@ -133,8 +138,8 @@ public: int m_palSize; int m_zbufmin; float zeus_matrix[3][3]; - float zeus_point[3]; - float zeus_point2[3]; + float zeus_trans[4]; + float zeus_light[3]; uint32_t zeus_texbase; int zeus_quad_size; @@ -145,6 +150,7 @@ public: uint32_t m_ucode[0x200]; uint32_t m_curUCodeSrc; uint32_t m_curPalTableSrc; + uint32_t m_texmodeReg; emu_timer *int_timer; emu_timer *vblank_timer; @@ -225,8 +231,18 @@ public: inline uint32_t frame_addr_from_xy(uint32_t x, uint32_t y, bool render) { - uint32_t addr = render ? frame_addr_from_phys_addr(m_renderRegs[0x4] << (15 + m_yScale)) - : frame_addr_from_phys_addr((m_zeusbase[0x38] >> 1) << (m_yScale << 1)); + uint32_t addr; + if (render) { + // Rendering is y location + addr = m_renderRegs[0x4] << (9 + m_yScale); + } + else { + // y.16:x.16 row/col + // Ignore col for now + addr = m_zeusbase[0x38] >> (16 - 9 - 2 * m_yScale); + } + //uint32_t addr = render ? frame_addr_from_phys_addr(m_renderRegs[0x4] << (15 + m_yScale)) + // : frame_addr_from_phys_addr((m_zeusbase[0x38] >> 1) << (m_yScale << 1)); addr += (y << (9 + m_yScale)) + x; return addr; } @@ -280,6 +296,8 @@ public: if (m_zeusbase[0x5e] & 0x40) { m_zeusbase[0x51]++; + //m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + //m_zeusbase[0x51] &= ~0xfe00; m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; m_zeusbase[0x51] &= ~0xfe00; } @@ -311,7 +329,14 @@ public: { return ((color & 0x7c00) << 9) | ((color & 0x3e0) << 6) | ((color & 0x8000) >> 5) | ((color & 0x1f) << 3); } - + inline uint32_t conv_rgb332_to_rgb32(uint8_t color) + { + uint32_t result; + result = ((((color) >> 0) & 0xe0) | (((color) >> 3) & 0x1c) | (((color) >> 6) & 0x03)) << 16; + result |= ((((color) << 3) & 0xe0) | (((color) >> 0) & 0x1c) | (((color) >> 3) & 0x03)) << 8; + result |= ((((color) << 6) & 0xc0) | (((color) << 4) & 0x30) | (((color) << 2) & 0x0c) | (((color) << 0) & 0x03)) << 0; + return result; + } #ifdef UNUSED_FUNCTION inline void WAVERAM_plot(int y, int x, uint32_t color) { @@ -392,7 +417,21 @@ public: uint32_t byteoffs = (y / 2) * (width * 2) + ((x / 2) << 2) + ((y & 1) << 1) + (x & 1); // Only grab RGB value for now byteoffs <<= 1; - return WAVERAM_READ8(base, byteoffs); + return WAVERAM_READ8(base, byteoffs + 0); + } + static inline uint8_t get_alpha_8bit_2x2_alpha(const void *base, int y, int x, int width) + { + uint32_t byteoffs = (y / 2) * (width * 2) + ((x / 2) << 2) + ((y & 1) << 1) + (x & 1); + // Only grab Alpha value for now + byteoffs <<= 1; + return WAVERAM_READ8(base, byteoffs + 1); + } + // 2x2 block size of r5g5r5 in 64 bits + static inline uint32_t get_rgb555(const void *base, int y, int x, int width) + { + uint32_t wordoffs = (y / 2) * (width * 2) + ((x / 2) << 2) + ((y & 1) << 1) + (x & 1); + uint16_t color = WAVERAM_READ16(base, wordoffs); + return ((color & 0x7c00) << 9) | ((color & 0x3e0) << 6) | ((color & 0x1f) << 3); } }; |