#include "emu.h" #include "includes/n64.h" #include "video/n64.h" namespace N64 { namespace RDP { void Framebuffer::Write(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b) { switch(m_misc_state->m_fb_size) { case PIXEL_SIZE_16BIT: Write16Bit(curpixel, r, g, b); break; case PIXEL_SIZE_32BIT: Write32Bit(curpixel, r, g, b); break; default: fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size); break; } } void Framebuffer::Write16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b) { #undef CVG_DRAW #ifdef CVG_DRAW int covdraw = (curpixel_cvg - 1) << 5; r = covdraw; g = covdraw; b = covdraw; #endif UINT32 fb = (m_misc_state->m_fb_address >> 1) + curpixel; UINT32 hb = fb; #if 0 if (m_misc_state->m_curpixel_cvg > 8 && m_other_modes->z_mode != 1) { stricterror("FBWRITE_16: curpixel_cvg %d", m_misc_state->m_curpixel_cvg); } #endif UINT16 finalcolor = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1); UINT32 finalcvg = 0; if (m_other_modes->color_on_cvg && !m_pre_wrap) { finalcolor = RREADIDX16(fb) & 0xfffe; } switch(m_other_modes->cvg_dest) { case 0: if (!m_rdp->GetBlender()->GetBlendEnable()) { finalcvg = (m_misc_state->m_curpixel_cvg - 1) & 7; RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1)); HWRITEADDR8(hb, finalcvg & 3); } else { finalcvg = m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg; if (finalcvg & 8) { finalcvg = 7; } RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1)); HWRITEADDR8(hb, finalcvg & 3); } break; case 1: finalcvg = (m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg) & 7; RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1)); HWRITEADDR8(hb, finalcvg & 3); break; case 2: RWRITEIDX16(fb, finalcolor | 1); HWRITEADDR8(hb, 3); break; case 3: RWRITEIDX16(fb, finalcolor | ((m_misc_state->m_curpixel_memcvg >> 2) & 1)); HWRITEADDR8(hb, m_misc_state->m_curpixel_memcvg & 3); break; } } void Framebuffer::Write32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b) { UINT32 fb = (m_misc_state->m_fb_address >> 2) + curpixel; UINT32 finalcolor = (r << 24) | (g << 16) | (b << 8);//cvg as 3 MSBs of alpha channel; UINT32 finalcvg = 0; #if 0 if (curpixel_cvg > 8 && m_other_modes->z_mode != 1) { stricterror("FBWRITE_16: curpixel_cvg %d", curpixel_cvg); } #endif if (m_other_modes->color_on_cvg && !m_pre_wrap) { finalcolor = RREADIDX32(fb) & 0xffffff00; } switch(m_other_modes->cvg_dest) { case 0: //normal if (!m_rdp->GetBlender()->GetBlendEnable()) { finalcvg = (m_misc_state->m_curpixel_cvg - 1) & 7; finalcolor |= (finalcvg << 5); RWRITEIDX32(fb, finalcolor); } else { finalcvg = m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg; if (finalcvg & 8) { finalcvg = 7; } finalcolor |= (finalcvg << 5); RWRITEIDX32(fb, finalcolor); } break; case 1: finalcvg = (m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg) & 7; finalcolor |= (finalcvg << 5); RWRITEIDX32(fb, finalcolor); break; case 2: RWRITEIDX32(fb, finalcolor | 0xE0); break; case 3: finalcolor |= (m_misc_state->m_curpixel_memcvg << 5); RWRITEIDX32(fb, finalcolor); break; } } void Framebuffer::Read(UINT32 curpixel) { switch(m_misc_state->m_fb_size) { case PIXEL_SIZE_16BIT: Read16Bit(curpixel); break; case PIXEL_SIZE_32BIT: Read32Bit(curpixel); break; default: fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size); break; } } void Framebuffer::Read16Bit(UINT32 curpixel) { UINT16 fword = RREADIDX16((m_misc_state->m_fb_address >> 1) + curpixel); UINT8 hbyte = HREADADDR8((m_misc_state->m_fb_address >> 1) + curpixel); m_rdp->GetMemoryColor()->i.r = GETHICOL(fword); m_rdp->GetMemoryColor()->i.g = GETMEDCOL(fword); m_rdp->GetMemoryColor()->i.b = GETLOWCOL(fword); if (m_other_modes->image_read_en) { m_misc_state->m_curpixel_memcvg = ((fword & 1) << 2) | (hbyte & 3); m_rdp->GetMemoryColor()->i.a = m_misc_state->m_curpixel_memcvg << 5; } else { m_misc_state->m_curpixel_memcvg = 7; m_rdp->GetMemoryColor()->i.a = 0xff; } } void Framebuffer::Read32Bit(UINT32 curpixel) { UINT32 mem = RREADIDX32((m_misc_state->m_fb_address >> 2) + curpixel); m_rdp->GetMemoryColor()->i.r = (mem >> 24) & 0xff; m_rdp->GetMemoryColor()->i.g = (mem >> 16) & 0xff; m_rdp->GetMemoryColor()->i.b = (mem >> 8) & 0xff; if (m_other_modes->image_read_en) { m_misc_state->m_curpixel_memcvg = (mem >> 5) & 7; m_rdp->GetMemoryColor()->i.a = (mem) & 0xff; } else { m_misc_state->m_curpixel_memcvg = 7; m_rdp->GetMemoryColor()->i.a = 0xff; } } void Framebuffer::Copy(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b) { switch(m_misc_state->m_fb_size) { case PIXEL_SIZE_16BIT: Copy16Bit(curpixel, r, g, b); break; case PIXEL_SIZE_32BIT: Copy32Bit(curpixel, r, g, b); break; default: fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size); break; } } void Framebuffer::Copy16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b) { UINT16 val = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((m_misc_state->m_curpixel_cvg >> 2) & 1); RWRITEIDX16((m_misc_state->m_fb_address >> 1) + curpixel, val); HWRITEADDR8((m_misc_state->m_fb_address >> 1) + curpixel, m_misc_state->m_curpixel_cvg & 3); } void Framebuffer::Copy32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b) { UINT32 val = (r << 24) | (g << 16) | (b << 8) | (m_misc_state->m_curpixel_cvg << 5); RWRITEIDX32((m_misc_state->m_fb_address >> 2) + curpixel, val); } void Framebuffer::Fill(UINT32 curpixel) { switch(m_misc_state->m_fb_size) { case PIXEL_SIZE_16BIT: Fill16Bit(curpixel); break; case PIXEL_SIZE_32BIT: Fill32Bit(curpixel); break; default: fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size); break; } } void Framebuffer::Fill16Bit(UINT32 curpixel) { UINT16 val; if (curpixel & 1) { val = m_rdp->GetFillColor32() & 0xffff; } else { val = (m_rdp->GetFillColor32() >> 16) & 0xffff; } RWRITEIDX16((m_misc_state->m_fb_address >> 1) + curpixel, val); HWRITEADDR8((m_misc_state->m_fb_address >> 1) + curpixel, ((val & 1) << 1) | (val & 1)); } void Framebuffer::Fill32Bit(UINT32 curpixel) { UINT32 fill_color = m_rdp->GetFillColor32(); RWRITEIDX32((m_misc_state->m_fb_address >> 2) + curpixel, fill_color); HWRITEADDR8((m_misc_state->m_fb_address >> 1) + (curpixel << 1), (fill_color & 0x10000) ? 3 : 0); HWRITEADDR8((m_misc_state->m_fb_address >> 1) + (curpixel << 1) + 1, (fill_color & 0x1) ? 3 : 0); } } // namespace RDP } // namespace N64