Unplot for the ZX Spectrum

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
andydansby
Member
Posts: 51
Joined: Fri May 27, 2016 8:58 pm

Unplot for the ZX Spectrum

Post by andydansby »

Hello:

I would like to perform an unplot on the Spectrum.

I am using the routine

Code: Select all

static void ZXplot(unsigned int x, unsigned int y, unsigned char colour)
{
        // Y works opposite to spectrum basic and range is larger on Y
        // ZXplot X range is 0-255 vs Basic 0-255
        // ZXplot Y range is 0-191 vs Basic 0-175

        //0,0 ZXPlot = top left vs Basic = bottom left
        //255,0 ZXplot = top right vs Basic = bottom right
        //0,175 ZXplot = bottom left vs BASIC = top left
        //255,175 ZXplot = bottom right vs BASIC = top right
        unsigned int MaxX = 255;
        unsigned int MaxY = 191;
        unsigned int MinX = 0;
        unsigned int MinY = 0;
        
        char *address;
   
        //if you exceed the edges
        if (x > MaxX) return;
        if (y > MaxY) return;
        if (x < MinX) return;
        if (y < MinY) return;
        
        address = zx_pxy2saddr(x,y);
        *address |= zx_px2bitmask(x);
   
        *zx_saddr2aaddr(address) = colour;
}
I am also using a line routine

Code: Select all

static void Line(int x1, int y1, int x2, int y2, int colour)
{
    int dy = y2 - y1;
    int dx = x2 - x1;
        
    int stepx;
        int stepy;
        int fraction = 0;

    if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
    if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
    dy <<= 1;        // dy is now 2*dy
    dx <<= 1;        // dx is now 2*dx

    ZXplot(x1,y1, colour);
    if (dx > dy) 
    {
        fraction = dy - (dx >> 1);        // same as 2*dy - dx
        while (x1 != x2) 
        {
           if (fraction >= 0) 
           {
               y1 += stepy;
               fraction -= dx;        // same as fraction -= 2*dx
           }
           x1 += stepx;
           fraction += dy;        // same as fraction -= 2*dy
           ZXplot(x1, y1, colour);
        }
     } 
         else 
         {
                fraction = dx - (dy >> 1);
                while (y1 != y2) 
                {
                        if (fraction >= 0) 
                        {
                                x1 += stepx;
                                fraction -= dy;
                        }
                        y1 += stepy;
           fraction += dx;
           ZXplot(x1, y1, colour);
        }
     }
}
The goal, of course, is to erase the line.

I thought by performing an XOR on the pixels, I could possibly erase the line.

Here's the routines I tried.

Code: Select all

static void ZXunplot(unsigned int x, unsigned int y, unsigned char colour)
{
        //works opposite to spectrum basic 
        // ZXplot X range is 0-255 vs Basic 0-255
        // ZXplot Y range is 0-191 vs Basic 0-175

        //0,0 ZXPlot = top left vs Basic = bottom left
        //255,0 ZXplot = top right vs Basic = bottom right
        //0,175 ZXplot = bottom left vs BASIC = top left
        //255,175 ZXplot = bottom right vs BASIC = top right
        unsigned int MaxX = 255;
        unsigned int MaxY = 191;
        unsigned int MinX = 0;
        unsigned int MinY = 0;
        
        char *address;
   
        //if you exceed the edges
        if (x > MaxX) return;
        if (y > MaxY) return;
        if (x < MinX) return;
        if (y < MinY) return;
        
        address = zx_pxy2saddr(x,y);

        *address && zx_px2bitmask(x);//trail left        bitwise XOR

        *zx_saddr2aaddr(address) = colour;
}
Of course, the Unline routine is the exact same, except I call unplot instead of plot.

I don't quite get an unplot with this routine, it does leave a nice little pattern on the screen when I perform the following calling routine.

Code: Select all

        for (r = 5; r < 90; r++)
        {
                Line(5, 10, r, 70, colour);
        }
   
        for (r = 5; r < 90; r++)
        {
                UnLine(5, 10, r, 70, colour);
        }
I am compiling using the New C library

Code: Select all

zcc +zx -vn -clib=new main.c -o circ -zorg=32768
Any help would be appreciated.

Thanks
Andy Dansby
User avatar
dom
Well known member
Posts: 2091
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I don't know if it's a copy paste problem, but:

Code: Select all

 *address && zx_px2bitmask(x);//trail left    bitwise XOR
should be &=
andydansby
Member
Posts: 51
Joined: Fri May 27, 2016 8:58 pm

Post by andydansby »

It was a typo, I did try &= for bitwise xor. It leaves quite a trail, interesting effect, but certainly does not unplot.

Thanks
Andy
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

You need to invert the mask to unplot:

Code: Select all

*address &= ~zx_px2bitmask(x);
zx_bitmask() is going to give you something like (in binary) 00010000 which indicates which bit to set for plot but to unplot you need to clear all but that bit ~00010000 = 11101111
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

xor should work too did you try this:

Code: Select all

*address ^= zx_px2bitmask(x);
andydansby
Member
Posts: 51
Joined: Fri May 27, 2016 8:58 pm

Post by andydansby »

The invert mask to unplot worked perfectly, thank you again Alvin. The Xor presented a problem, leaving behind a Moire like trail. an interesting effect, but not what I was looking for.

Andy
Post Reply