Ejemplo n.º 1
0
        //-------------------------------------------------
        //  transpen_mask - return a mask of pens that
        //  whose indirect values match the given
        //  transcolor
        //-------------------------------------------------
        public u32 transpen_mask(gfx_element gfx, u32 color, indirect_pen_t transcolor)
        {
            u32 entry = gfx.colorbase() + (color % gfx.colors()) * gfx.granularity();

            // make sure we are in range
            assert(entry < m_indirect_pens.size());
            assert(gfx.depth() <= 32);

            // either gfx->color_depth entries or as many as we can get up until the end
            int count = (int)Math.Min((UInt32)gfx.depth(), m_indirect_pens.size() - entry);

            // set a bit anywhere the transcolor matches
            u32 mask = 0;

            for (int bit = 0; bit < count; bit++)
            {
                if (m_indirect_pens[(int)entry++] == transcolor)
                {
                    mask |= (UInt32)1 << bit;
                }
            }

            // return the final mask
            return(mask);
        }
Ejemplo n.º 2
0
Archivo: digfx.cs Proyecto: kwanboy/mcs
        // decoding
        //-------------------------------------------------
        //  decode_gfx - parse gfx decode info and
        //  create gfx elements
        //-------------------------------------------------
        void decode_gfx(gfx_decode_entry [] gfxdecodeinfo)
        {
            // skip if nothing to do
            if (gfxdecodeinfo == null)
            {
                return;
            }

            // local variables to hold mutable copies of gfx layout data
            gfx_layout glcopy;

            std.vector <u32> extxoffs = new std.vector <u32>(0);
            std.vector <u32> extyoffs = new std.vector <u32>(0);

            // loop over all elements
            for (u8 curgfx = 0; curgfx < digfx_global.MAX_GFX_ELEMENTS && curgfx < gfxdecodeinfo.Length && gfxdecodeinfo[curgfx].gfxlayout != null; curgfx++)
            {
                gfx_decode_entry gfx = gfxdecodeinfo[curgfx];

                // extract the scale factors and xormask
                u32 xscale  = GFXENTRY_GETXSCALE(gfx.flags);
                u32 yscale  = GFXENTRY_GETYSCALE(gfx.flags);
                u32 xormask = GFXENTRY_ISREVERSE(gfx.flags) ? 7U : 0U;

                // resolve the region
                u32 region_length;
                ListBytesPointer region_base;  //const u8     *region_base;
                u8           region_width;
                endianness_t region_endianness;

                if (gfx.memory_region != null)
                {
                    device_t basedevice = (GFXENTRY_ISDEVICE(gfx.flags)) ? device() : device().owner();
                    if (GFXENTRY_ISRAM(gfx.flags))
                    {
                        memory_share share = basedevice.memshare(gfx.memory_region);
                        //assert(share != NULL);
                        region_length     = (UInt32)(8 * share.bytes());
                        region_base       = share.ptr(); //region_base = reinterpret_cast<u8 *>(share->ptr());
                        region_width      = share.bytewidth();
                        region_endianness = share.endianness();
                    }
                    else
                    {
                        memory_region region = basedevice.memregion(gfx.memory_region);
                        //assert(region != NULL);
                        region_length     = 8 * region.bytes();
                        region_base       = new ListBytesPointer(region.base_(), 0); //region_base = region->base();
                        region_width      = region.bytewidth();
                        region_endianness = region.endianness();
                    }
                }
                else
                {
                    region_length     = 0;
                    region_base       = null;
                    region_width      = 1;
                    region_endianness = ENDIANNESS_NATIVE;
                }

                if (region_endianness != ENDIANNESS_NATIVE)
                {
                    switch (region_width)
                    {
                    case 2:
                        xormask |= 0x08;
                        break;

                    case 4:
                        xormask |= 0x18;
                        break;

                    case 8:
                        xormask |= 0x38;
                        break;
                    }
                }


                // copy the layout into our temporary variable
                glcopy = new gfx_layout(gfx.gfxlayout);  //memcpy(&glcopy, gfx.gfxlayout, sizeof(gfx_layout));


                // if the character count is a region fraction, compute the effective total
                if (IS_FRAC(glcopy.total))
                {
                    //assert(region_length != 0);
                    glcopy.total = region_length / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total);
                }

                // for non-raw graphics, decode the X and Y offsets
                if (glcopy.planeoffset[0] != digfx_global.GFX_RAW)
                {
                    // copy the X and Y offsets into our temporary arrays
                    extxoffs.resize((int)(glcopy.width * xscale));
                    extyoffs.resize((int)(glcopy.height * yscale));

                    //memcpy(&extxoffs[0], (glcopy.extxoffs != null) ? glcopy.extxoffs : glcopy.xoffset, glcopy.width * sizeof(UInt32));
                    //memcpy(&extyoffs[0], (glcopy.extyoffs != null) ? glcopy.extyoffs : glcopy.yoffset, glcopy.height * sizeof(UInt32));
                    for (int i = 0; i < glcopy.width; i++)
                    {
                        extxoffs[i] = glcopy.extxoffs != null ? glcopy.extxoffs[i] : glcopy.xoffset[i];
                    }

                    for (int i = 0; i < glcopy.height; i++)
                    {
                        extyoffs[i] = glcopy.extyoffs != null ? glcopy.extyoffs[i] : glcopy.yoffset[i];
                    }

                    // always use the extended offsets here
                    glcopy.extxoffs = extxoffs;
                    glcopy.extyoffs = extyoffs;

                    // expand X and Y by the scale factors
                    if (xscale > 1)
                    {
                        glcopy.width *= (UInt16)xscale;
                        for (int j = glcopy.width - 1; j >= 0; j--)
                        {
                            extxoffs[j] = extxoffs[(int)(j / xscale)];
                        }
                    }
                    if (yscale > 1)
                    {
                        glcopy.height *= (UInt16)yscale;
                        for (int j = glcopy.height - 1; j >= 0; j--)
                        {
                            extyoffs[j] = extyoffs[(int)(j / yscale)];
                        }
                    }

                    // loop over all the planes, converting fractions
                    for (int j = 0; j < glcopy.planes; j++)
                    {
                        u32 value1 = glcopy.planeoffset[j];
                        if (IS_FRAC(value1))
                        {
                            //assert(region_length != 0);
                            glcopy.planeoffset[j] = FRAC_OFFSET(value1) + region_length * FRAC_NUM(value1) / FRAC_DEN(value1);
                        }
                    }

                    // loop over all the X/Y offsets, converting fractions
                    for (int j = 0; j < glcopy.width; j++)
                    {
                        u32 value2 = extxoffs[j];
                        if (digfx_global.IS_FRAC(value2))
                        {
                            //assert(region_length != 0);
                            extxoffs[j] = FRAC_OFFSET(value2) + region_length * FRAC_NUM(value2) / FRAC_DEN(value2);
                        }
                    }

                    for (int j = 0; j < glcopy.height; j++)
                    {
                        u32 value3 = extyoffs[j];
                        if (IS_FRAC(value3))
                        {
                            //assert(region_length != 0);
                            extyoffs[j] = FRAC_OFFSET(value3) + region_length * FRAC_NUM(value3) / FRAC_DEN(value3);
                        }
                    }
                }

                // otherwise, just use the line modulo
                else
                {
                    int base_   = (int)gfx.start;
                    int end     = (int)(region_length / 8);
                    int linemod = (int)glcopy.yoffset[0];
                    while (glcopy.total > 0)
                    {
                        int elementbase   = (int)(base_ + (glcopy.total - 1) * glcopy.charincrement / 8);
                        int lastpixelbase = elementbase + glcopy.height * linemod / 8 - 1;
                        if (lastpixelbase < end)
                        {
                            break;
                        }
                        glcopy.total--;
                    }
                }

                // allocate the graphics
                //m_gfx[curgfx] = new gfx_element(m_palette, glcopy, region_base != null ? region_base + gfx.start : null, xormask, gfx.total_color_codes, gfx.color_codes_start);
                m_gfx[curgfx] = new gfx_element(m_paletteDevice.target.palette_interface, glcopy, region_base != null ? new ListBytesPointer(region_base, (int)gfx.start) : null, xormask, gfx.total_color_codes, gfx.color_codes_start);
            }

            m_decoded = true;
        }
Ejemplo n.º 3
0
 public u32 transpen_mask(gfx_element gfx, u32 color, indirect_pen_t transcolor)
 {
     return(dipalette.transpen_mask(gfx, color, transcolor));
 }
Ejemplo n.º 4
0
        //-------------------------------------------------
        //  render_object: Internal processing callback
        //  that renders to the backing bitmap and then
        //  copies the result  to the destination.
        //-------------------------------------------------
        void render_object(bitmap_ind16 bitmap, rectangle cliprect, Pointer <uint16_t> entry)  //void atari_motion_objects_device::render_object(bitmap_ind16 &bitmap, const rectangle &cliprect, const uint16_t *entry)
        {
            // select the gfx element and save off key information
            int         rawcode          = (int)m_codemask.extract(entry);
            gfx_element gfx              = m_gfxdecode.op0.gfx(m_gfxlookup[rawcode >> 8]);
            int         save_granularity = gfx.granularity();
            int         save_colorbase   = (int)gfx.colorbase();
            int         save_colors      = (int)gfx.colors();

            gfx.set_granularity(1);
            gfx.set_colorbase(0);
            gfx.set_colors(65536);

            // extract data from the various words
            int code     = (int)m_codelookup[rawcode];
            int color    = m_colorlookup[m_colormask.extract(entry)];
            int xpos     = m_xposmask.extract(entry) + m_xoffset;
            int ypos     = -m_yposmask.extract(entry);
            int hflip    = m_hflipmask.extract(entry);
            int vflip    = m_vflipmask.extract(entry);
            int width    = m_widthmask.extract(entry) + 1;
            int height   = m_heightmask.extract(entry) + 1;
            int priority = m_prioritymask.extract(entry);

            // compute the effective color, merging in priority
            color  = (color * save_granularity) | (priority << PRIORITY_SHIFT);
            color += m_atari_motion_objects_config.m_palettebase;

            // add in the scroll positions if we're not in absolute coordinates
            if (m_absolutemask.extract(entry) == 0)
            {
                xpos -= (int)m_xscroll;
                ypos -= (int)m_yscroll;
            }

            // adjust for height
            ypos -= height << m_tileyshift;

            // handle previous hold bits
            if (m_next_xpos != 123456)
            {
                xpos = (int)m_next_xpos;
            }
            m_next_xpos = 123456;

            // check for the hold bit
            if (m_neighbormask.extract(entry) != 0)
            {
                if (!m_atari_motion_objects_config.m_nextneighbor)
                {
                    xpos = (int)m_last_xpos + m_tilewidth;
                }
                else
                {
                    m_next_xpos = (uint32_t)(xpos + m_tilewidth);
                }
            }
            m_last_xpos = (uint32_t)xpos;

            // adjust the final coordinates
            xpos &= m_bitmapxmask;
            ypos &= m_bitmapymask;
            if (xpos >= bitmap.width())
            {
                xpos -= m_bitmapwidth;
            }
            if (ypos >= bitmap.height())
            {
                ypos -= m_bitmapheight;
            }

            // is this one special?
            if (m_specialmask.mask() == 0 || m_specialmask.extract(entry) != m_atari_motion_objects_config.m_specialvalue)
            {
                // adjust for h flip
                int xadv = m_tilewidth;
                if (hflip != 0)
                {
                    xpos += (width - 1) << m_tilexshift;
                    xadv  = -xadv;
                }

                // adjust for v flip
                int yadv = m_tileheight;
                if (vflip != 0)
                {
                    ypos += (height - 1) << m_tileyshift;
                    yadv  = -yadv;
                }

                // standard order is: loop over Y first, then X
                if (!m_atari_motion_objects_config.m_swapxy)
                {
                    // loop over the height
                    for (int y = 0, sy = ypos; y < height; y++, sy += yadv)
                    {
                        // clip the Y coordinate
                        if (sy <= cliprect.top() - m_tileheight)
                        {
                            code += width;
                            continue;
                        }
                        else if (sy > cliprect.bottom())
                        {
                            break;
                        }

                        // loop over the width
                        for (int x = 0, sx = xpos; x < width; x++, sx += xadv, code++)
                        {
                            // clip the X coordinate
                            if (sx <= -cliprect.left() - m_tilewidth || sx > cliprect.right())
                            {
                                continue;
                            }

                            // draw the sprite
                            gfx.transpen_raw(bitmap, cliprect, (u32)code, (u32)color, hflip, vflip, sx, sy, m_atari_motion_objects_config.m_transpen);
                            mark_dirty(sx, sx + m_tilewidth - 1, sy, sy + m_tileheight - 1);
                        }
                    }
                }

                // alternative order is swapped
                else
                {
                    // loop over the width
                    for (int x = 0, sx = xpos; x < width; x++, sx += xadv)
                    {
                        // clip the X coordinate
                        if (sx <= cliprect.left() - m_tilewidth)
                        {
                            code += height;
                            continue;
                        }
                        else if (sx > cliprect.right())
                        {
                            break;
                        }

                        // loop over the height
                        for (int y = 0, sy = ypos; y < height; y++, sy += yadv, code++)
                        {
                            // clip the X coordinate
                            if (sy <= -cliprect.top() - m_tileheight || sy > cliprect.bottom())
                            {
                                continue;
                            }

                            // draw the sprite
                            gfx.transpen_raw(bitmap, cliprect, (u32)code, (u32)color, hflip, vflip, sx, sy, m_atari_motion_objects_config.m_transpen);
                            mark_dirty(sx, sx + m_tilewidth - 1, sy, sy + m_tileheight - 1);
                        }
                    }
                }
            }

            // restore original gfx information
            gfx.set_granularity((u16)save_granularity);
            gfx.set_colorbase((u16)save_colorbase);
            gfx.set_colors((u32)save_colors);
        }
Ejemplo n.º 5
0
        //void apply_stain(bitmap_ind16 &bitmap, uint16_t *pf, uint16_t *mo, int x, int y);

        // memory access
        //uint16_t &slipram(int offset) { return m_slipram[offset]; }


        // device-level overrides

        //-------------------------------------------------
        //  device_start: Start up the device
        //-------------------------------------------------
        protected override void device_start()
        {
            // call parent
            base.device_start();

            // verify configuration
            gfx_element gfx = m_gfxdecode.op0.gfx(m_atari_motion_objects_config.m_gfxindex);

            if (gfx == null)
            {
                throw new emu_fatalerror("No gfxelement #{0}!", m_atari_motion_objects_config.m_gfxindex);
            }

            // determine the masks
            m_linkmask.set(m_atari_motion_objects_config.m_link_entry);
            m_codemask.set(m_atari_motion_objects_config.m_code_entry);
            m_colormask.set(m_atari_motion_objects_config.m_color_entry);
            m_xposmask.set(m_atari_motion_objects_config.m_xpos_entry);
            m_yposmask.set(m_atari_motion_objects_config.m_ypos_entry);
            m_widthmask.set(m_atari_motion_objects_config.m_width_entry);
            m_heightmask.set(m_atari_motion_objects_config.m_height_entry);
            m_hflipmask.set(m_atari_motion_objects_config.m_hflip_entry);
            m_vflipmask.set(m_atari_motion_objects_config.m_vflip_entry);
            m_prioritymask.set(m_atari_motion_objects_config.m_priority_entry);
            m_neighbormask.set(m_atari_motion_objects_config.m_neighbor_entry);
            m_absolutemask.set(m_atari_motion_objects_config.m_absolute_entry);

            // derive tile information
            m_tilewidth  = gfx.width();
            m_tileheight = gfx.height();
            m_tilexshift = compute_log(m_tilewidth);
            m_tileyshift = compute_log(m_tileheight);

            // derive bitmap information
            m_bitmapwidth  = round_to_powerof2(m_xposmask.mask());
            m_bitmapheight = round_to_powerof2(m_yposmask.mask());
            m_bitmapxmask  = m_bitmapwidth - 1;
            m_bitmapymask  = m_bitmapheight - 1;

            // derive sprite information
            m_entrycount    = round_to_powerof2(m_linkmask.mask());
            m_entrybits     = compute_log(m_entrycount);
            m_spriteramsize = m_atari_motion_objects_config.m_bankcount * m_entrycount;
            m_spriterammask = m_spriteramsize - 1;
            m_slipshift     = (m_atari_motion_objects_config.m_slipheight != 0) ? compute_log(m_atari_motion_objects_config.m_slipheight) : 0;
            m_slipramsize   = m_bitmapheight >> m_slipshift;
            m_sliprammask   = m_slipramsize - 1;
            if (m_atari_motion_objects_config.m_maxperline == 0)
            {
                m_atari_motion_objects_config.m_maxperline = MAX_PER_BANK;
            }

            // Get the slipram from the share if not already explicitly set
            if (m_slipram == null)
            {
                m_slipram = new Pointer <u16>(m_slipramshare.op);
            }

            // allocate and initialize the code lookup
            int codesize = round_to_powerof2((int)m_codemask.mask());

            m_codelookup.resize((size_t)codesize);
            for (int i = 0; i < codesize; i++)
            {
                m_codelookup[i] = (uint32_t)i;
            }

            // allocate and initialize the color lookup
            int colorsize = round_to_powerof2((int)m_colormask.mask());

            m_colorlookup.resize((size_t)colorsize);
            for (int i = 0; i < colorsize; i++)
            {
                m_colorlookup[i] = (uint8_t)i;
            }

            // allocate and the gfx lookup
            int gfxsize = codesize / 256;

            m_gfxlookup.resize((size_t)gfxsize);
            for (int i = 0; i < gfxsize; i++)
            {
                m_gfxlookup[i] = m_atari_motion_objects_config.m_gfxindex;
            }

            // allocate a timer to periodically force update
            m_force_update_timer = timer_alloc(TID_FORCE_UPDATE);
            m_force_update_timer.adjust(m_divideo.screen().time_until_pos(0));

            // register for save states
            save_item(NAME(new { m_bank }));
            save_item(NAME(new { m_xscroll }));
            save_item(NAME(new { m_yscroll }));
        }