Exemple #1
0
void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, colortable_t *ctable,
                                   const UINT8 *source, int base_color, int global_x_offset, int bank_base, bitmap_ind8 &priority_bitmap, UINT32 pri_mask )
{
    //  gfx_element *gfx = gfxs[chip];
    int flipscreen = m_flipscreen;
    int i, num, inc, offs[5];
    int is_flakatck = (ctable == NULL);

    if (is_flakatck)
    {
        num = 0x40;
        inc = -0x20;
        source += 0x3f * 0x20;
        offs[0] = 0x0e;
        offs[1] = 0x0f;
        offs[2] = 0x06;
        offs[3] = 0x04;
        offs[4] = 0x08;
    }
    else    /* all others */
    {
        /* TODO: sprite limit is supposed to be per-line! (check MT #00185) */
        num = 0x40;
        //num = (k007121->ctrlram[0x03] & 0x40) ? 0x80 : 0x40; /* WRONG!!! (needed by combatsc)  */

        inc = 5;
        offs[0] = 0x00;
        offs[1] = 0x01;
        offs[2] = 0x02;
        offs[3] = 0x03;
        offs[4] = 0x04;
        /* when using priority buffer, draw front to back */
        if (pri_mask != -1)
        {
            source += (num - 1)*inc;
            inc = -inc;
        }
    }

    for (i = 0; i < num; i++)
    {
        int number = source[offs[0]];               /* sprite number */
        int sprite_bank = source[offs[1]] & 0x0f;   /* sprite bank */
        int sx = source[offs[3]];                   /* vertical position */
        int sy = source[offs[2]];                   /* horizontal position */
        int attr = source[offs[4]];             /* attributes */
        int xflip = source[offs[4]] & 0x10;     /* flip x */
        int yflip = source[offs[4]] & 0x20;     /* flip y */
        int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
        int width, height;
        int transparent_mask;
        static const int x_offset[4] = {0x0,0x1,0x4,0x5};
        static const int y_offset[4] = {0x0,0x2,0x8,0xa};
        int x,y, ex, ey, flipx, flipy, destx, desty;

        if (attr & 0x01) sx -= 256;
        if (sy >= 240) sy -= 256;

        number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4);
        number = number << 2;
        number += (sprite_bank >> 2) & 3;

        /* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
        /* to a palette entry */
        if (is_flakatck)
            transparent_mask = 1 << 0;
        else
            transparent_mask = colortable_get_transpen_mask(ctable, gfx, color, 0);

        if (!is_flakatck || source[0x00])   /* Flak Attack needs this */
        {
            number += bank_base;

            switch (attr & 0xe)
            {
            case 0x06:
                width = height = 1;
                break;
            case 0x04:
                width = 1;
                height = 2;
                number &= (~2);
                break;
            case 0x02:
                width = 2;
                height = 1;
                number &= (~1);
                break;
            case 0x00:
                width = height = 2;
                number &= (~3);
                break;
            case 0x08:
                width = height = 4;
                number &= (~3);
                break;
            default:
                width = 1;
                height = 1;
//                  logerror("Unknown sprite size %02x\n", attr & 0xe);
//                  popmessage("Unknown sprite size %02x\n", attr & 0xe);
            }

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    ex = xflip ? (width - 1 - x) : x;
                    ey = yflip ? (height - 1 - y) : y;

                    if (flipscreen)
                    {
                        flipx = !xflip;
                        flipy = !yflip;
                        destx = 248 - (sx + x * 8);
                        desty = 248 - (sy + y * 8);
                    }
                    else
                    {
                        flipx = xflip;
                        flipy = yflip;
                        destx = global_x_offset + sx + x * 8;
                        desty = sy + y * 8;
                    }

                    if (pri_mask != -1)
                        pdrawgfx_transmask(bitmap,cliprect,gfx,
                                           number + x_offset[ex] + y_offset[ey],
                                           color,
                                           flipx,flipy,
                                           destx,desty,
                                           priority_bitmap,pri_mask,
                                           transparent_mask);
                    else
                        drawgfx_transmask(bitmap,cliprect,gfx,
                                          number + x_offset[ex] + y_offset[ey],
                                          color,
                                          flipx,flipy,
                                          destx,desty,
                                          transparent_mask);
                }
            }
        }

        source += inc;
    }
}
static void draw_sprites( running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect )
{
    docastle_state *state = machine.driver_data<docastle_state>();
    int offs;

    bitmap_fill(machine.priority_bitmap, NULL, 1);

    for (offs = state->m_spriteram_size - 4; offs >= 0; offs -= 4)
    {
        int sx, sy, flipx, flipy, code, color;

        if (machine.gfx[1]->total_elements > 256)
        {
            /* spriteram

             indoor soccer appears to have a slightly different spriteram
             format to the other games, allowing a larger number of sprite
             tiles

             yyyy yyyy  xxxx xxxx  TX-T pppp  tttt tttt

             y = ypos
             x = xpos
             X = x-flip
             T = extra tile number bits
             p = palette
             t = tile number

             */

            code = state->m_spriteram[offs + 3];
            color = state->m_spriteram[offs + 2] & 0x0f;
            sx = ((state->m_spriteram[offs + 1] + 8) & 0xff) - 8;
            sy = state->m_spriteram[offs];
            flipx = state->m_spriteram[offs + 2] & 0x40;
            flipy = 0;
            if (state->m_spriteram[offs + 2] & 0x10) code += 0x100;
            if (state->m_spriteram[offs + 2] & 0x80) code += 0x200;
        }
        else
        {
            /* spriteram

            this is the standard spriteram layout, used by most games

             yyyy yyyy  xxxx xxxx  YX-p pppp  tttt tttt

             y = ypos
             x = xpos
             X = x-flip
             Y = y-flip
             p = palette
             t = tile number

             */

            code = state->m_spriteram[offs + 3];
            color = state->m_spriteram[offs + 2] & 0x1f;
            sx = ((state->m_spriteram[offs + 1] + 8) & 0xff) - 8;
            sy = state->m_spriteram[offs];
            flipx = state->m_spriteram[offs + 2] & 0x40;
            flipy = state->m_spriteram[offs + 2] & 0x80;
        }

        if (flip_screen_get(machine))
        {
            sx = 240 - sx;
            sy = 240 - sy;
            flipx = !flipx;
            flipy = !flipy;
        }

        /* first draw the sprite, visible */
        pdrawgfx_transmask(bitmap,cliprect,machine.gfx[1],
                           code,
                           color,
                           flipx,flipy,
                           sx,sy,
                           machine.priority_bitmap,
                           0x00,0x80ff);

        /* then draw the mask, behind the background but obscuring following sprites */
        pdrawgfx_transmask(bitmap,cliprect,machine.gfx[1],
                           code,
                           color,
                           flipx,flipy,
                           sx,sy,
                           machine.priority_bitmap,
                           0x02,0x7fff);
    }
}