Author Topic: Plotting pixels  (Read 2497 times)

0 Members and 1 Guest are viewing this topic.

Offline ervin

  • Supporter
  • 6128 Plus
  • *
  • Posts: 1.406
  • Country: au
    • index.php?action=treasury
  • Liked: 1102
  • Likes Given: 1295
Plotting pixels
« on: 04:59, 29 October 15 »
Hi folks.

I'm trying to figure out how to paint pixels in mode 1 and mode 2, by modifying the mode 0 routines found on cpcmania.com.
SDCC vs z88dk: Comparing size and speed

Can someone please suggest what I'd need to do to the 2 functions below?
Ideally, I'd like mode 1 and mode 2 versions of each function.
I just can't figure it out!
 :'(

Thanks for any help.

Code: [Select]
void PutPixelMode0(unsigned char nX, unsigned char nY, unsigned char nColor)
{
  unsigned char nPixel = 0;
  unsigned int nAddress = 0xC000 + ((nY / 8) * 80) + ((nY % 8) * 2048) + (nX / 2);
  nPixel = nX % 2;

  SetMode0PixelColor((unsigned char *)nAddress, nColor, nPixel);
}

void SetMode0PixelColor(unsigned char *pByteAddress, unsigned char nColor, unsigned char nPixel)
{
  unsigned char nByte = *pByteAddress;

  if(nPixel == 0)
  {
    nByte &= 85;

    if(nColor & 1)
      nByte |= 128;

    if(nColor & 2)
      nByte |= 8;

    if(nColor & 4)
      nByte |= 32;

    if(nColor & 8)
      nByte |= 2;
  }
  else
  {
    nByte &= 170;

    if(nColor & 1)
      nByte |= 64;

    if(nColor & 2)
      nByte |= 4;

    if(nColor & 4)
      nByte |= 16;

    if(nColor & 8)
      nByte |= 1;
  }

  *pByteAddress = nByte;
}
My (cancelled) entry for the CPCRetroDev 2017 Competition http://www.cpcwiki.eu/forum/programming/my-cpcretrodev-2017-entry/
FAST line drawing in CPCtelera http://www.cpcwiki.eu/forum/programming/drawing-lines-with-cpctelera-sdcc/
RUNCPC My entry for the CPCRetroDev 2015 Competition http://www.cpc-power.com/index.php?page=detail&num=12494

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.939
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 1155
  • Likes Given: 1923
Re: Plotting pixels
« Reply #1 on: 10:19, 29 October 15 »
So in Mode 0 a Byte has a Left Most Pixel & a Right Most Pixel along the Xpos line, so perhaps where it reads "nX / 2" needs to be changed to "nX / 4" for Mode 1 and "nX / 8" for Mode 2. That nPixel line may need to change as well to have those multiples, though I may have that wrong.


SetMode0PixelColor is doing some sort of check with those Left Most Pixels & Right Most Pixels, but there's 4 colour groups, I'm not too sure what's going on there, some sort of Alternative Ink colour switch?
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Offline Tai

  • CPC464
  • **
  • Posts: 27
  • Country: 00
  • Liked: 15
  • Likes Given: 106
Re: Plotting pixels
« Reply #2 on: 11:58, 29 October 15 »

You can check here how pixels are arranged in a byte for each video mode.

Painting pixels: Introduction to video memory




Offline ronaldo

  • Dev
  • 6128 Plus
  • *****
  • Posts: 641
  • Country: es
    • Fremos Blog
  • Liked: 921
  • Likes Given: 822
Re: Plotting pixels
« Reply #3 on: 12:07, 29 October 15 »
Assuming you have X, Y coordinates in pixels, you only have to write your pixels, codified in screen pixel format, directly to memory:
Code: [Select]
u8* pvmem;
pvmem = cpct_getScreenPtr((u8*)0xC000, x / 2, y);

// For mode 0
*pvmem = cpct_px2byteM0 (color_pixel_1, color_pixel_2);

// For mode 1
*pvmem = cpct_px2byteM1 (color_pixel_1, color_pixel_2, color_pixel_3, color_pixel_4);
And that's it :) .

Also, for your reference, screen pixel format is described in cpct_px2byteM0 documentation ;).
« Last Edit: 12:12, 29 October 15 by ronaldo »

Offline Fessor

  • CPC6128
  • ****
  • Posts: 235
  • Country: de
  • Liked: 204
  • Likes Given: 46
Re: Plotting pixels
« Reply #4 on: 12:11, 29 October 15 »
What the Routine do is:
It gets the byte from the Screen-Memory, saves with &= 85 (&x0101010) / &= 170 (&x10101010) the color of the other Pixel and also cleans the bits for the pixelcolor to be set and looks with bit is set at the Pen-Number and then sets the corresponding bit for the screen-memory-format. The result is written back to Memory.

nbyte &= 85 means nbyte = nbyte AND 85. The percent stands for a Modulo-Operation. For Mode 1 nPixel = nX % 4 (for four Pixel per Byte), Mode 2 nPixel = nX % 8 (for 8 Pixel per Byte)

For Mode 1 the Bitmaps of the three other Pixels have to be saved so you need four ifs for the four pixel-positions, and 4 masks to save the other pixels. For Mode 2 eight ifs for each Pixelposition in the Byte and 8 Masks to save the other Pixels.

Offline ervin

  • Supporter
  • 6128 Plus
  • *
  • Posts: 1.406
  • Country: au
    • index.php?action=treasury
  • Liked: 1102
  • Likes Given: 1295
Re: Plotting pixels
« Reply #5 on: 12:18, 29 October 15 »
Thanks for your help everyone!
I'll have a try!
 :D

My (cancelled) entry for the CPCRetroDev 2017 Competition http://www.cpcwiki.eu/forum/programming/my-cpcretrodev-2017-entry/
FAST line drawing in CPCtelera http://www.cpcwiki.eu/forum/programming/drawing-lines-with-cpctelera-sdcc/
RUNCPC My entry for the CPCRetroDev 2015 Competition http://www.cpc-power.com/index.php?page=detail&num=12494

Offline ronaldo

  • Dev
  • 6128 Plus
  • *****
  • Posts: 641
  • Country: es
    • Fremos Blog
  • Liked: 921
  • Likes Given: 822
Re: Plotting pixels
« Reply #6 on: 15:30, 29 October 15 »
Also, if you wanted to pring a single pixel, mixing it with actual contents of video memory, I'd do this (Warning! Untested code!):
Code: [Select]
#define M0_PIXEL1_MASK 0xAA
#define M0_PIXEL2_MASK 0x55

//         x,y: pixel coordinates in pixels
// pixel_color: PEN color for the pixel to be lightened
//
void putpixel(u8 x, u8 y, u8 pixel_color) {
   u8* pvmem, pix1 = 0, pix2 = 0;
 
   // Get a pointer to the byte where the pixel is
   pvmem = cpct_getScreenPtr((u8*)0xC000, x / 2, y);

   // Check if pixel is even (pixel 1) or odd (pixel 2)
   if (x & 1) {
      // Odd pixel = Pixel 2 = Right pixel of the byte
      // Even pixel will stay, Odd pixel have to be removed
      *pvmem &= M0_PIXEL1_MASK;
      pix1    = pixel_color;
   } else {
      // Even pixel = Pixel 1 = Left pixel of the byte
      // Odd pixel will stay, Even pixel have to be removed
      *pvmem &= M0_PIXEL2_MASK;
      pix2    = pixel_color;
   }

   // Set the color of the pixel
   *pvmem |= cpct_px2byteM0 (pix1, pix2);
}

Offline TFM

  • Visit the mysteries of the CPC at www.futureos.de
  • Supporter
  • 6128 Plus
  • *
  • Posts: 9.899
  • Country: aq
  • Space Chicken for FutureOS is free!
    • index.php?action=treasury
    • FutureOS - The revolution on CPC!
  • Liked: 1983
  • Likes Given: 4650
Re: Plotting pixels
« Reply #7 on: 19:09, 29 October 15 »
IMHO the best thing is to have totally separated PLOT routines for MODE 0-3. They are worlds apart. MODE 2 can be very quick.


Please take a look at my FIOLIB, you will find quick routines there.  :)
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

Offline ervin

  • Supporter
  • 6128 Plus
  • *
  • Posts: 1.406
  • Country: au
    • index.php?action=treasury
  • Liked: 1102
  • Likes Given: 1295
Re: Plotting pixels
« Reply #8 on: 00:24, 30 October 15 »
Also, if you wanted to pring a single pixel, mixing it with actual contents of video memory, I'd do this (Warning! Untested code!):
Code: [Select]
#define M0_PIXEL1_MASK 0xAA
#define M0_PIXEL2_MASK 0x55

//         x,y: pixel coordinates in pixels
// pixel_color: PEN color for the pixel to be lightened
//
void putpixel(u8 x, u8 y, u8 pixel_color) {
   u8* pvmem, pix1 = 0, pix2 = 0;
 
   // Get a pointer to the byte where the pixel is
   pvmem = cpct_getScreenPtr((u8*)0xC000, x / 2, y);

   // Check if pixel is even (pixel 1) or odd (pixel 2)
   if (x & 1) {
      // Odd pixel = Pixel 2 = Right pixel of the byte
      // Even pixel will stay, Odd pixel have to be removed
      *pvmem &= M0_PIXEL1_MASK;
      pix1    = pixel_color;
   } else {
      // Even pixel = Pixel 1 = Left pixel of the byte
      // Odd pixel will stay, Even pixel have to be removed
      *pvmem &= M0_PIXEL2_MASK;
      pix2    = pixel_color;
   }

   // Set the color of the pixel
   *pvmem |= cpct_px2byteM0 (pix1, pix2);
}

That's fantastic, thanks @ronaldo!

[EDIT] I got it working! But only after I swapped pix1 and pix2 in the IF block.

Code: [Select]
   if (x & 1) {
      // Odd pixel = Pixel 2 = Right pixel of the byte
      // Even pixel will stay, Odd pixel have to be removed
      *pvmem &= M0_PIXEL1_MASK;
      pix2    = pixel_color;
   } else {
      // Even pixel = Pixel 1 = Left pixel of the byte
      // Odd pixel will stay, Even pixel have to be removed
      *pvmem &= M0_PIXEL2_MASK;
      pix1    = pixel_color;
   }
« Last Edit: 01:19, 30 October 15 by ervin »
My (cancelled) entry for the CPCRetroDev 2017 Competition http://www.cpcwiki.eu/forum/programming/my-cpcretrodev-2017-entry/
FAST line drawing in CPCtelera http://www.cpcwiki.eu/forum/programming/drawing-lines-with-cpctelera-sdcc/
RUNCPC My entry for the CPCRetroDev 2015 Competition http://www.cpc-power.com/index.php?page=detail&num=12494

Offline ronaldo

  • Dev
  • 6128 Plus
  • *****
  • Posts: 641
  • Country: es
    • Fremos Blog
  • Liked: 921
  • Likes Given: 822
Re: Plotting pixels
« Reply #9 on: 12:32, 01 November 15 »
Correct, @ervin. I mistakenly mixed up both pixel values (didn't properly read my own comments  :laugh: ).

Offline ervin

  • Supporter
  • 6128 Plus
  • *
  • Posts: 1.406
  • Country: au
    • index.php?action=treasury
  • Liked: 1102
  • Likes Given: 1295
Re: Plotting pixels
« Reply #10 on: 13:45, 01 November 15 »
Correct, @ervin. I mistakenly mixed up both pixel values (didn't properly read my own comments  :laugh: ).

Thanks @ronaldo.
I'm glad to know I managed to figure it out.
 :)
 
My (cancelled) entry for the CPCRetroDev 2017 Competition http://www.cpcwiki.eu/forum/programming/my-cpcretrodev-2017-entry/
FAST line drawing in CPCtelera http://www.cpcwiki.eu/forum/programming/drawing-lines-with-cpctelera-sdcc/
RUNCPC My entry for the CPCRetroDev 2015 Competition http://www.cpc-power.com/index.php?page=detail&num=12494