Esempio n. 1
0
            static void draw_everything(Mame.osd_bitmap bitmap, bool fullDraw)
            {
                _BytePtr _base = new _BytePtr(bitmap.line[starty], startx);
                uint[] sprite_buffer = new uint[(32 * 8) + 256];

                _BytePtr overall_priority_base = new _BytePtr(overall_priority, (turbo_fbpla & 8) << 6);
                _BytePtr sprite_priority_base = new _BytePtr(sprite_priority, (turbo_fbpla & 7) << 7);
                _BytePtr road_gfxdata_base = new _BytePtr(road_gfxdata, (turbo_opc << 5) & 0x7e0);
                UShortSubArray road_palette_base = new UShortSubArray(road_expanded_palette, (turbo_fbcol & 1) << 4);

                int dx = deltax, dy = deltay, rowsize = (bitmap.line[1].offset - bitmap.line[0].offset) * 8 / bitmap.depth;
                UShortSubArray colortable;
                int x, y, i;

                /* expand the appropriate delta */
                if ((Mame.Machine.orientation & Mame.ORIENTATION_SWAP_XY) != 0)
                    dx *= rowsize;
                else
                    dy *= rowsize;

                /* determine the color offset */
                colortable = new UShortSubArray(Mame.Machine.pens, (turbo_fbcol & 6) << 6);

                /* loop over rows */
                for (y = 4; y < (28 * 8) - 4; y++, _base.offset += dy)
                {
                    int sel, coch, babit, slipar_acciar, area, area1, area2, area3, area4, area5, road = 0;
                    uint[] sprite_data = sprite_buffer;
                    _BytePtr dest = new _BytePtr(_base);

                    /* compute the Y sum between opa and the current scanline (p. 141) */
                    int va = (y + turbo_opa) & 0xff;

                    /* the upper bit of OPC inverts the road */
                    if ((turbo_opc & 0x80) == 0) va ^= 0xff;

                    /* clear the sprite buffer and draw the road sprites */
                    Array.Clear(sprite_buffer, 0, 32 * 8);
                    draw_road_sprites(sprite_buffer, y);

                    /* loop over 8-pixel chunks */
                    dest.offset += dx * 8;
                    int sdi = 8;
                    for (x = 8; x < (32 * 8); x += 8)
                    {
                        int area5_buffer = road_gfxdata_base[0x4000 + (x >> 3)];
                        byte back_data = Generic.videoram[(y / 8) * 32 + (x / 8) - 33];
                        ushort backbits_buffer = back_expanded_data[(back_data << 3) | (y & 7)];

                        /* loop over columns */
                        for (i = 0; i < 8; i++, dest.offset += dx)
                        {
                            uint sprite = sprite_data[sdi++];

                            /* compute the X sum between opb and the current column; only the carry matters (p. 141) */
                            int carry = (x + i + turbo_opb) >> 8;

                            /* the carry selects which inputs to use (p. 141) */
                            if (carry != 0)
                            {
                                sel = turbo_ipb;
                                coch = turbo_ipc >> 4;
                            }
                            else
                            {
                                sel = turbo_ipa;
                                coch = turbo_ipc & 15;
                            }

                            /* at this point we also compute area5 (p. 141) */
                            area5 = (area5_buffer >> 3) & 0x10;
                            area5_buffer <<= 1;

                            /* now look up the rest of the road bits (p. 142) */
                            area1 = road_gfxdata[0x0000 | ((sel & 15) << 8) | va];
                            area1 = ((area1 + x + i) >> 8) & 0x01;
                            area2 = road_gfxdata[0x1000 | ((sel & 15) << 8) | va];
                            area2 = ((area2 + x + i) >> 7) & 0x02;
                            area3 = road_gfxdata[0x2000 | ((sel >> 4) << 8) | va];
                            area3 = ((area3 + x + i) >> 6) & 0x04;
                            area4 = road_gfxdata[0x3000 | ((sel >> 4) << 8) | va];
                            area4 = ((area4 + x + i) >> 5) & 0x08;

                            /* compute the final area value and look it up in IC18/PR1115 (p. 144) */
                            area = area5 | area4 | area3 | area2 | area1;
                            babit = road_enable_collide[area] & 0x07;

                            /* note: SLIPAR is 0 on the road surface only */
                            /*		 ACCIAR is 0 on the road surface and the striped edges only */
                            slipar_acciar = road_enable_collide[area] & 0x30;
                            if (road == 0 && (slipar_acciar & 0x20) != 0)
                            {
                                road = 1;
                                draw_offroad_sprites(sprite_buffer, x + i + 2, y);
                            }

                            /* perform collision detection here */
                            turbo_collision |= collision_map[(uint)((sprite >> 24) & 7) | (uint)(slipar_acciar >> 1)];

                            /* we only need to continue if we're actually drawing */
                            if (fullDraw)
                            {
                                int bacol, red, grn, blu, priority, backbits, mx;

                                /* also use the coch value to look up color info in IC13/PR1114 and IC21/PR1117 (p. 144) */
                                bacol = road_palette_base[coch & 15];

                                /* at this point, do the character lookup */
                                backbits = backbits_buffer & 3;
                                backbits_buffer >>= 2;
                                backbits = back_palette[backbits | (back_data & 0xfc)];

                                /* look up the sprite priority in IC11/PR1122 */
                                priority = sprite_priority_base[sprite >> 25];

                                /* use that to look up the overall priority in IC12/PR1123 */
                                mx = overall_priority_base[(uint)((priority & 7) | ((sprite >> 21) & 8) | ((back_data >> 3) & 0x10) | ((backbits << 2) & 0x20) | (babit << 6))];

                                /* the input colors consist of a mix of sprite, road and 1's & 0's */
                                red = (int)(0x040000 | ((bacol & 0x001f) << 13) | ((backbits & 1) << 12) | ((sprite << 4) & 0x0ff0));
                                grn = (int)(0x080000 | ((bacol & 0x03e0) << 9) | ((backbits & 2) << 12) | ((sprite >> 3) & 0x1fe0));
                                blu = (int)(0x100000 | ((bacol & 0x7c00) << 5) | ((backbits & 4) << 12) | ((sprite >> 10) & 0x3fc0));

                                /* we then go through a muxer; normally these values are inverted, but */
                                /* we've already taken care of that when we generated the palette */
                                red = (red >> mx) & 0x10;
                                grn = (grn >> mx) & 0x20;
                                blu = (blu >> mx) & 0x40;
                                dest[0] = (byte)colortable[mx | red | grn | blu];
                            }
                        }
                    }
                }
            }
Esempio n. 2
0
        /* This is a bit slow, but it works. I'll speed it up later */
        static void nemesis_drawgfx_zoomup(Mame.osd_bitmap dest, Mame.GfxElement gfx,
                uint code, uint color, int flipx, int flipy, int sx, int sy,
                Mame.rectangle clip, int transparency, int transparent_color, int scale)
        {
            int ex, ey, y, start, dy;
            _BytePtr sd;
            _BytePtr bm;
            int col;
            Mame.rectangle myclip = new Mame.rectangle(); ;

            int dda_x = 0;
            int dda_y = 0;
            int ex_count;
            int ey_count;
            int real_x;
            int ysize;
            int xsize;
            UShortSubArray paldata;	/* ASG 980209 */
            int transmask;

            if (gfx == null) return;

            code %= gfx.total_elements;
            color %= (uint)gfx.total_colors;

            transmask = 1 << transparent_color;

            if ((gfx.pen_usage[code] & ~transmask) == 0)
                /* character is totally transparent, no need to draw */
                return;


            if ((Mame.Machine.orientation & Mame.ORIENTATION_SWAP_XY) != 0)
            {
                int temp;

                temp = sx;
                sx = sy;
                sy = temp;

                temp = flipx;
                flipx = flipy;
                flipy = temp;

                if (clip != null)
                {
                    /* clip and myclip might be the same, so we need a temporary storage */
                    temp = clip.min_x;
                    myclip.min_x = clip.min_y;
                    myclip.min_y = temp;
                    temp = clip.max_x;
                    myclip.max_x = clip.max_y;
                    myclip.max_y = temp;
                    clip = myclip;
                }
            }
            if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0)
            {
                sx = dest.width - gfx.width - sx;

                if (clip != null)
                {
                    int temp;

                    /* clip and myclip might be the same, so we need a temporary storage */
                    temp = clip.min_x;
                    myclip.min_x = dest.width - 1 - clip.max_x;
                    myclip.max_x = dest.width - 1 - temp;
                    myclip.min_y = clip.min_y;
                    myclip.max_y = clip.max_y;
                    clip = myclip;
                }
            }
            if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0)
            {
                sy = dest.height - gfx.height - sy;

                if (clip != null)
                {
                    int temp;

                    myclip.min_x = clip.min_x;
                    myclip.max_x = clip.max_x;
                    /* clip and myclip might be the same, so we need a temporary storage */
                    temp = clip.min_y;
                    myclip.min_y = dest.height - 1 - clip.max_y;
                    myclip.max_y = dest.height - 1 - temp;
                    clip = myclip;
                }
            }


            /* check bounds */
            xsize = gfx.width;
            ysize = gfx.height;
            /* Clipping currently done in code loop */
            ex = sx + xsize - 1;
            ey = sy + ysize - 1;
            /*	if (ex >= dest.width) ex = dest.width-1;
                if (clip && ex > clip.max_x) ex = clip.max_x;
                if (sx > ex) return;
                if (ey >= dest.height) tey = dest.height-1;
                if (clip && ey > clip.max_y) ey = clip.max_y;
                if (sy > ey) return;
            */
            /* start = code * gfx.height; */
            if (flipy != 0)	/* Y flip */
            {
                start = (int)(code * gfx.height + gfx.height - 1);
                dy = -1;
            }
            else		/* normal */
            {
                start = (int)(code * gfx.height);
                dy = 1;
            }



            paldata = new UShortSubArray(gfx.colortable, (int)(gfx.color_granularity * color));

            if (flipx != 0)	/* X flip */
            {
                if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0)
                    y = sy + ysize - 1;
                else
                    y = sy;
                dda_y = 0x80;
                ey_count = sy;
                do
                {
                    if (y >= clip.min_y && y <= clip.max_y)
                    {
                        if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0)
                        {
                            bm = new _BytePtr(dest.line[y], sx + xsize - 1);
                            real_x = sx + xsize - 1;
                        }
                        else
                        {
                            bm = new _BytePtr(dest.line[y], sx);
                            real_x = sx;
                        }
                        sd = new _BytePtr(gfx.gfxdata, start * gfx.line_modulo + xsize - 1);
                        dda_x = 0x80;
                        ex_count = sx;
                        col = sd[0];
                        do
                        {
                            if ((real_x <= clip.max_x) && (real_x >= clip.min_x))
                                if (col != transparent_color) bm[0] = (byte)paldata[col];
                            if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0)
                            {
                                bm.offset--;
                                real_x--;
                            }
                            else
                            {
                                bm.offset++;
                                real_x++;
                            }
                            dda_x -= scale;
                            if (dda_x <= 0)
                            {
                                dda_x += 0x80;
                                sd.offset--;
                                ex_count++;
                                col = sd[0];
                            }
                        } while (ex_count <= ex);
                    }
                    if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0)
                        y--;
                    else
                        y++;
                    dda_y -= scale;
                    if (dda_y <= 0)
                    {
                        dda_y += 0x80;
                        start += dy;
                        ey_count++;
                    }

                } while (ey_count <= ey);
            }
            else		/* normal */
            {
                if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0)
                    y = sy + ysize - 1;
                else
                    y = sy;
                dda_y = 0x80;
                ey_count = sy;
                do
                {
                    if (y >= clip.min_y && y <= clip.max_y)
                    {
                        if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0)
                        {
                            bm = new _BytePtr(dest.line[y], sx + xsize - 1);
                            real_x = sx + xsize - 1;
                        }
                        else
                        {
                            bm = new _BytePtr(dest.line[y], sx);
                            real_x = sx;
                        }
                        sd = new _BytePtr(gfx.gfxdata, start * gfx.line_modulo);
                        dda_x = 0x80;
                        ex_count = sx;
                        col = sd[0];
                        do
                        {
                            if ((real_x <= clip.max_x) && (real_x >= clip.min_x))
                                if (col != transparent_color) bm[0] = (byte)paldata[col];
                            if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0)
                            {
                                bm.offset--;
                                real_x--;
                            }
                            else
                            {
                                bm.offset++;
                                real_x++;
                            }
                            dda_x -= scale;
                            if (dda_x <= 0)
                            {
                                dda_x += 0x80;
                                sd.offset++;
                                ex_count++;
                                col = sd[0];
                            }
                        } while (ex_count <= ex);
                    }
                    if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0)
                        y--;
                    else
                        y++;
                    dda_y -= scale;
                    if (dda_y <= 0)
                    {
                        dda_y += 0x80;
                        start += dy;
                        ey_count++;
                    }

                } while (ey_count <= ey);
            }
        }