/******************************************************************** Sega Model 2 3D rasterization functions ********************************************************************/ #undef MODEL2_CHECKER #undef MODEL2_TEXTURED #undef MODEL2_TRANSLUCENT #ifndef MODEL2_FUNC #error "Model 2 renderer: No function defined!" #endif #ifndef MODEL2_FUNC_NAME #error "Model 2 renderer: No function name defined!" #endif #if MODEL2_FUNC == 0 #undef MODEL2_CHECKER #undef MODEL2_TEXTURED #undef MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 1 #undef MODEL2_CHECKER #undef MODEL2_TEXTURED #define MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 2 #undef MODEL2_CHECKER #define MODEL2_TEXTURED #undef MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 3 #undef MODEL2_CHECKER #define MODEL2_TEXTURED #define MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 4 #define MODEL2_CHECKER #undef MODEL2_TEXTURED #undef MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 5 #define MODEL2_CHECKER #undef MODEL2_TEXTURED #define MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 6 #define MODEL2_CHECKER #define MODEL2_TEXTURED #undef MODEL2_TRANSLUCENT #elif MODEL2_FUNC == 7 #define MODEL2_CHECKER #define MODEL2_TEXTURED #define MODEL2_TRANSLUCENT #else #error "Model 2 renderer: Invalif function selected!" #endif #ifndef MODEL2_TEXTURED /* non-textured render path */ static void MODEL2_FUNC_NAME(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid) { #if !defined( MODEL2_TRANSLUCENT) const poly_extra_data *extra = (const poly_extra_data *)extradata; model2_state *state = extra->state; bitmap_t *destmap = (bitmap_t *)dest; UINT32 *p = BITMAP_ADDR32(destmap, scanline, 0); /* extract color information */ const UINT16 *colortable_r = (const UINT16 *)&state->m_colorxlat[0x0000/4]; const UINT16 *colortable_g = (const UINT16 *)&state->m_colorxlat[0x4000/4]; const UINT16 *colortable_b = (const UINT16 *)&state->m_colorxlat[0x8000/4]; const UINT16 *lumaram = (const UINT16 *)state->m_lumaram; const UINT16 *palram = (const UINT16 *)state->m_paletteram32; UINT32 lumabase = extra->lumabase; UINT32 color = extra->colorbase; UINT8 luma; UINT32 tr, tg, tb; int x; #endif /* if it's translucent, there's nothing to render */ #if defined( MODEL2_TRANSLUCENT) return; #else luma = lumaram[BYTE_XOR_LE(lumabase + (0xf << 3))] & 0x3F; color = palram[BYTE_XOR_LE(color + 0x1000)] & 0x7fff; colortable_r += ((color >> 0) & 0x1f) << 8; colortable_g += ((color >> 5) & 0x1f) << 8; colortable_b += ((color >> 10) & 0x1f) << 8; /* we have the 6 bits of luma information along with 5 bits per color component */ /* now build and index into the master color lookup table and extract the raw RGB values */ tr = colortable_r[BYTE_XOR_LE(luma)] & 0xff; tg = colortable_g[BYTE_XOR_LE(luma)] & 0xff; tb = colortable_b[BYTE_XOR_LE(luma)] & 0xff; /* build the final color */ color = MAKE_RGB(tr, tg, tb); for(x = extent->startx; x < extent->stopx; x++) #if defined(MODEL2_CHECKER) if ((x^scanline) & 1) p[x] = color; #else p[x] = color; #endif #endif } #else /* textured render path */ static void MODEL2_FUNC_NAME(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid) { const poly_extra_data *extra = (const poly_extra_data *)extradata; model2_state *state = extra->state; bitmap_t *destmap = (bitmap_t *)dest; UINT32 *p = BITMAP_ADDR32(destmap, scanline, 0); UINT32 tex_width = extra->texwidth; UINT32 tex_height = extra->texheight; /* extract color information */ const UINT16 *colortable_r = (const UINT16 *)&state->m_colorxlat[0x0000/4]; const UINT16 *colortable_g = (const UINT16 *)&state->m_colorxlat[0x4000/4]; const UINT16 *colortable_b = (const UINT16 *)&state->m_colorxlat[0x8000/4]; const UINT16 *lumaram = (const UINT16 *)state->m_lumaram; const UINT16 *palram = (const UINT16 *)state->m_paletteram32; UINT32 colorbase = extra->colorbase; UINT32 lumabase = extra->lumabase; UINT32 tex_x = extra->texx; UINT32 tex_y = extra->texy; UINT32 tex_x_mask, tex_y_mask; UINT32 tex_mirr_x = extra->texmirrorx; UINT32 tex_mirr_y = extra->texmirrory; UINT32 *sheet = extra->texsheet; float ooz = extent->param[0].start; float uoz = extent->param[1].start; float voz = extent->param[2].start; float dooz = extent->param[0].dpdx; float duoz = extent->param[1].dpdx; float dvoz = extent->param[2].dpdx; int x; tex_x_mask = tex_width - 1; tex_y_mask = tex_height - 1; colorbase = palram[BYTE_XOR_LE(colorbase + 0x1000)] & 0x7fff; colortable_r += ((colorbase >> 0) & 0x1f) << 8; colortable_g += ((colorbase >> 5) & 0x1f) << 8; colortable_b += ((colorbase >> 10) & 0x1f) << 8; for(x = extent->startx; x < extent->stopx; x++, uoz += duoz, voz += dvoz, ooz += dooz) { float z = recip_approx(ooz) * 256.0f; INT32 u = uoz * z; INT32 v = voz * z; UINT32 tr, tg, tb; UINT16 t; UINT8 luma; int u2; int v2; #if defined(MODEL2_CHECKER) if ( ((x^scanline) & 1) == 0 ) continue; #endif u2 = (u >> 8) & tex_x_mask; v2 = (v >> 8) & tex_y_mask; if ( tex_mirr_x ) u2 = ( tex_width - 1 ) - u2; if ( tex_mirr_y ) v2 = ( tex_height - 1 ) - v2; t = get_texel( tex_x, tex_y, u2, v2, sheet ); #if defined(MODEL2_TRANSLUCENT) if ( t == 0x0f ) continue; #endif luma = lumaram[BYTE_XOR_LE(lumabase + (t << 3))] & 0x3f; /* we have the 6 bits of luma information along with 5 bits per color component */ /* now build and index into the master color lookup table and extract the raw RGB values */ tr = colortable_r[BYTE_XOR_LE(luma)] & 0xff; tg = colortable_g[BYTE_XOR_LE(luma)] & 0xff; tb = colortable_b[BYTE_XOR_LE(luma)] & 0xff; p[x] = MAKE_RGB(tr, tg, tb); } } #endif