C64Lib.Core.MOS6569.draw_sprites C# (CSharp) Method

draw_sprites() public method

public draw_sprites ( ) : void
return void
        void draw_sprites()
        {
            int i;
            int snum, sbit;		// Sprite number/bit mask
            int spr_coll = 0, gfx_coll = 0;

            //// Clear sprite collision buffer
            //{
            //    UInt32* lp = (UInt32*)spr_coll_buf_ptr - 1;
            //    for (i = 0; i < C64Display.DISPLAY_X / 4; i++)
            //        *++lp = 0;

            //}

            // Clear sprite collision buffer
            for (int b = 0; b < spr_coll_buf.Length; b++)
            {
                spr_coll_buf[b] = 0;
            }

            // Loop for all sprites
            for (snum = 0, sbit = 1; snum < 8; snum++, sbit <<= 1)
            {

                // Is sprite visible?
                if ((spr_draw & sbit) != 0 && mx[snum] <= C64Display.DISPLAY_X - 32)
                {
                    //byte* p = chunky_line_start + mx[snum] + 8;
                    int pIndex = _chunkyLineStartIndex + mx[snum] + 8;

                    //byte* q = (byte*)spr_coll_buf_ptr + mx[snum] + 8;
                    //int qIndex = spr_coll_buf_index + mx[snum] + 8;
                    int qIndex = mx[snum] + 8;

                    byte color = spr_color[snum];

                    // Fetch sprite data and mask
                    //UInt32 sdata = (UInt32)((spr_draw_data_ptr[snum * 4] << 24) |
                    //                          (spr_draw_data_ptr[snum * 4 + 1] << 16) |
                    //                          (spr_draw_data_ptr[snum * 4 + 2] << 8));
                    UInt32 sdata = (UInt32)((spr_draw_data[snum * 4] << 24) |
                                            (spr_draw_data[snum * 4 + 1] << 16) |
                                            (spr_draw_data[snum * 4 + 2] << 8));

                    int spr_mask_pos = mx[snum] + 8;	// Sprite bit position in fore_mask_buf

                    //byte* fmbp = fore_mask_buf_ptr + (spr_mask_pos / 8);
                    int fmbpIndex = 0 + (spr_mask_pos / 8);

                    //if (fmbpIndex == 0)
                    //{
                    //    Debug.WriteLine("fmbpIndex == 0");
                    //}

                    int sshift = spr_mask_pos & 7;
                    //UInt32 fore_mask = (UInt32)((((*(fmbp + 0) << 24) | (*(fmbp + 1) << 16) | (*(fmbp + 2) << 8)
                    //                | (*(fmbp + 3))) << sshift) | (*(fmbp + 4) >> (8 - sshift)));
                    UInt32 fore_mask = (UInt32)(((
                                    (fore_mask_buf[(fmbpIndex + 0)] << 24) |
                                    (fore_mask_buf[(fmbpIndex + 1)] << 16) |
                                    (fore_mask_buf[(fmbpIndex + 2)] << 8) |
                                    (fore_mask_buf[(fmbpIndex + 3)])) << sshift) |
                                    (fore_mask_buf[(fmbpIndex + 4)] >> (8 - sshift)
                                    ));

                    if ((mxe & sbit) != 0)
                    {		// X-expanded
                        if (mx[snum] > C64Display.DISPLAY_X - 56)
                            continue;

                        UInt32 sdata_l = 0, sdata_r = 0, fore_mask_r;
                        //fore_mask_r = (UInt32)((((*(fmbp + 4) << 24) | (*(fmbp + 5) << 16) | (*(fmbp + 6) << 8)
                        //        | (*(fmbp + 7))) << sshift) | (*(fmbp + 8) >> (8 - sshift)));

                        fore_mask_r = (UInt32)(((
                                      (fore_mask_buf[(fmbpIndex + 4)] << 24) |
                                      (fore_mask_buf[(fmbpIndex + 5)] << 16) |
                                      (fore_mask_buf[(fmbpIndex + 6)] << 8) |
                                      (fore_mask_buf[(fmbpIndex + 7)])) << sshift) |
                                      (fore_mask_buf[(fmbpIndex + 8)] >> (8 - sshift)
                                      ));

                        if ((mmc & sbit) != 0)
                        {	// Multicolor mode
                            UInt32 plane0_l, plane0_r, plane1_l, plane1_r;

                            // Expand sprite data
                            //sdata_l = (UInt32)(MultiExpTable_ptr[sdata >> 24 & 0xff] << 16 | MultiExpTable_ptr[sdata >> 16 & 0xff]);
                            //sdata_r = (UInt32)(MultiExpTable_ptr[sdata >> 8 & 0xff] << 16);
                            sdata_l = (UInt32)(MultiExpTable[sdata >> 24 & 0xff] << 16 | MultiExpTable[sdata >> 16 & 0xff]);
                            sdata_r = (UInt32)(MultiExpTable[sdata >> 8 & 0xff] << 16);

                            // Convert sprite chunky pixels to bitplanes
                            plane0_l = (sdata_l & 0x55555555) | (sdata_l & 0x55555555) << 1;
                            plane1_l = (sdata_l & 0xaaaaaaaa) | (sdata_l & 0xaaaaaaaa) >> 1;
                            plane0_r = (sdata_r & 0x55555555) | (sdata_r & 0x55555555) << 1;
                            plane1_r = (sdata_r & 0xaaaaaaaa) | (sdata_r & 0xaaaaaaaa) >> 1;

                            // Collision with graphics?
                            if ((fore_mask & (plane0_l | plane1_l)) != 0 || (fore_mask_r & (plane0_r | plane1_r)) != 0)
                            {
                                gfx_coll |= sbit;
                                if ((mdp & sbit) != 0)
                                {
                                    plane0_l &= ~fore_mask;	// Mask sprite if in background
                                    plane1_l &= ~fore_mask;
                                    plane0_r &= ~fore_mask_r;
                                    plane1_r &= ~fore_mask_r;
                                }
                            }

                            // Paint sprite
                            for (i = 0; i < 32; i++, plane0_l <<= 1, plane1_l <<= 1)
                            {
                                byte col;
                                if ((plane1_l & 0x80000000) != 0)
                                {
                                    if ((plane0_l & 0x80000000) != 0)
                                        col = mm1_color;
                                    else
                                        col = color;
                                }
                                else
                                {
                                    if ((plane0_l & 0x80000000) != 0)
                                        col = mm0_color;
                                    else
                                        continue;
                                }
                                //if (q[i] != 0)
                                //    spr_coll |= q[i] | sbit;
                                //else
                                //{
                                //    p[i] = col;
                                //    q[i] = (byte)sbit;
                                //}
                                if (spr_coll_buf[qIndex + i] != 0)
                                    spr_coll |= spr_coll_buf[qIndex + i] | sbit;
                                else
                                {
                                    _display.SetPixel(pIndex + i, col);
                                    spr_coll_buf[qIndex + i] = (byte)sbit;
                                }

                            }
                            for (; i < 48; i++, plane0_r <<= 1, plane1_r <<= 1)
                            {
                                byte col;
                                if ((plane1_r & 0x80000000) != 0)
                                {
                                    if ((plane0_r & 0x80000000) != 0)
                                        col = mm1_color;
                                    else
                                        col = color;
                                }
                                else
                                {
                                    if ((plane0_r & 0x80000000) != 0)
                                        col = mm0_color;
                                    else
                                        continue;
                                }
                                //if (q[_chunkyLineStartIndex + i] != 0)
                                //    spr_coll |= q[_chunkyLineStartIndex + i] | sbit;
                                //else
                                //{
                                //    p[i] = col;
                                //    q[i] = (byte)sbit;
                                //}
                                if (spr_coll_buf[qIndex + i] != 0)
                                    spr_coll |= spr_coll_buf[qIndex + i] | sbit;
                                else
                                {
                                    _display.SetPixel(pIndex + i, col);
                                    spr_coll_buf[qIndex + i] = (byte)sbit;
                                }
                            }

                        }
                        else
                        {			// Standard mode

                            // Expand sprite data
                            //sdata_l = (UInt32)(ExpTable_ptr[sdata >> 24 & 0xff] << 16 | ExpTable_ptr[sdata >> 16 & 0xff]);
                            //sdata_r = (UInt32)(ExpTable_ptr[sdata >> 8 & 0xff] << 16);
                            sdata_l = (UInt32)(ExpTable[ExpTable_index + (sdata >> 24 & 0xff)] << 16 |
                                                ExpTable[ExpTable_index + (sdata >> 16 & 0xff)]);
                            sdata_r = (UInt32)(ExpTable[ExpTable_index + (sdata >> 8 & 0xff)] << 16);

                            // Collision with graphics?
                            if ((fore_mask & sdata_l) != 0 || (fore_mask_r & sdata_r) != 0)
                            {
                                gfx_coll |= sbit;
                                if ((mdp & sbit) != 0)
                                {
                                    sdata_l &= ~fore_mask;	// Mask sprite if in background
                                    sdata_r &= ~fore_mask_r;
                                }
                            }

                            // Paint sprite
                            //for (i = 0; i < 32; i++, sdata_l <<= 1)
                            //    if ((sdata_l & 0x80000000) != 0)
                            //    {
                            //        if (q[i] != 0)	// Collision with sprite?
                            //            spr_coll |= q[i] | sbit;
                            //        else
                            //        {		// Draw pixel if no collision
                            //            p[i] = color;
                            //            q[i] = (byte)sbit;
                            //        }
                            //    }
                            //for (; i < 48; i++, sdata_r <<= 1)
                            //    if ((sdata_r & 0x80000000) != 0)
                            //    {
                            //        if (q[i] != 0) 	// Collision with sprite?
                            //            spr_coll |= q[i] | sbit;
                            //        else
                            //        {		// Draw pixel if no collision
                            //            p[i] = color;
                            //            q[i] = (byte)sbit;
                            //        }
                            //    }
                            for (i = 0; i < 32; i++, sdata_l <<= 1)
                                if ((sdata_l & 0x80000000) != 0)
                                {
                                    if (spr_coll_buf[qIndex + i] != 0)	// Collision with sprite?
                                        spr_coll |= spr_coll_buf[qIndex + i] | sbit;
                                    else
                                    {		// Draw pixel if no collision
                                        _display.SetPixel(pIndex + i, color);
                                        spr_coll_buf[qIndex + i] = (byte)sbit;
                                    }
                                }
                            for (; i < 48; i++, sdata_r <<= 1)
                                if ((sdata_r & 0x80000000) != 0)
                                {
                                    if (spr_coll_buf[qIndex + i] != 0) 	// Collision with sprite?
                                        spr_coll |= spr_coll_buf[qIndex + i] | sbit;
                                    else
                                    {		// Draw pixel if no collision
                                        _display.SetPixel(pIndex + i, color);
                                        spr_coll_buf[qIndex + i] = (byte)sbit;
                                    }
                                }
                        }

                    }
                    else
                    {				// Unexpanded

                        if ((mmc & sbit) != 0)
                        {	// Multicolor mode
                            UInt32 plane0, plane1;

                            // Convert sprite chunky pixels to bitplanes
                            plane0 = (sdata & 0x55555555) | (sdata & 0x55555555) << 1;
                            plane1 = (sdata & 0xaaaaaaaa) | (sdata & 0xaaaaaaaa) >> 1;

                            // Collision with graphics?
                            if ((fore_mask & (plane0 | plane1)) != 0)
                            {
                                gfx_coll |= sbit;
                                if ((mdp & sbit) != 0)
                                {
                                    plane0 &= ~fore_mask;	// Mask sprite if in background
                                    plane1 &= ~fore_mask;
                                }
                            }

                            // Paint sprite
                            for (i = 0; i < 24; i++, plane0 <<= 1, plane1 <<= 1)
                            {
                                byte col;
                                if ((plane1 & 0x80000000) != 0)
                                {
                                    if ((plane0 & 0x80000000) != 0)
                                        col = mm1_color;
                                    else
                                        col = color;
                                }
                                else
                                {
                                    if ((plane0 & 0x80000000) != 0)
                                        col = mm0_color;
                                    else
                                        continue;
                                }
                                //if (q[i] != 0)
                                //    spr_coll |= q[i] | sbit;
                                //else
                                //{
                                //    p[i] = col;
                                //    q[i] = (byte)sbit;
                                //}
                                if (spr_coll_buf[qIndex + i] != 0)
                                    spr_coll |= spr_coll_buf[qIndex + i] | sbit;
                                else
                                {
                                    _display.SetPixel(pIndex + i, col);
                                    spr_coll_buf[qIndex + i] = (byte)sbit;
                                }

                            }

                        }
                        else
                        {			// Standard mode

                            // Collision with graphics?
                            if ((fore_mask & sdata) != 0)
                            {
                                gfx_coll |= sbit;
                                if ((mdp & sbit) != 0)
                                    sdata &= ~fore_mask;	// Mask sprite if in background
                            }

                            // Paint sprite
                            for (i = 0; i < 24; i++, sdata <<= 1)
                                if ((sdata & 0x80000000) != 0)
                                {
                                    //if (q[i] != 0)
                                    //{	// Collision with sprite?
                                    //    spr_coll |= q[i] | sbit;
                                    //}
                                    //else
                                    //{		// Draw pixel if no collision
                                    //    p[i] = color;
                                    //    q[i] = (byte)sbit;
                                    //}
                                    if (spr_coll_buf[qIndex + i] != 0)
                                    {	// Collision with sprite?
                                        spr_coll |= spr_coll_buf[qIndex + i] | sbit;
                                    }
                                    else
                                    {		// Draw pixel if no collision
                                        _display.SetPixel(pIndex + i, color);
                                        spr_coll_buf[qIndex + i] = (byte)sbit;
                                    }
                                }
                        }
                    }
                }
            }

            if (GlobalPrefs.ThePrefs.SpriteCollisions)
            {

                // Check sprite-sprite collisions
                if (clx_spr != 0)
                    clx_spr |= (byte)spr_coll;
                else
                {
                    clx_spr |= (byte)spr_coll;
                    irq_flag |= 0x04;
                    if ((irq_mask & 0x04) != 0)
                    {
                        irq_flag |= 0x80;
                        _cpu.TriggerVICIRQ();
                    }
                }

                // Check sprite-background collisions
                if (clx_bgr != 0)
                    clx_bgr |= (byte)gfx_coll;
                else
                {
                    clx_bgr |= (byte)gfx_coll;
                    irq_flag |= 0x02;
                    if ((irq_mask & 0x02) != 0)
                    {
                        irq_flag |= 0x80;
                        _cpu.TriggerVICIRQ();
                    }
                }
            }
        }