UnderwareDESIGN

PlayBASIC => Beginners => Topic started by: kevin on November 22, 2017, 09:12:17 AM

Title: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: kevin on November 22, 2017, 09:12:17 AM

PlayBASIC LIVE:   How to Make a 320 by 200 16 colour Palette Mapped Screen  (22 Nov 2017)

   In this video we take a look at how we could use the Palette mapping library to create a classic 8 bit styled screen that's 320 by 200 pixels with only 16 colours.    Which is something like the  type of graphic hardware you'd find in that classic 8bit / 16 bit computers.  In this example the programmer can use any of the 16 colours anyway on the the screen at any time,  this was generally not the case for classic  8Bit systems, which tend to have various limitations on how many colours can appears within a bitmap,  which makes some of the old artists even more impressive. 

Anyway, you can find the source code on our forums of course with thousands of other examples..  Have fun !

Video:


Example Code:
[pbcode]

// Include the palette Mapping library
   #include "paletteMapping"
   

   // Define    
   Dim Palette(256)
   
   
   SetPalette(Palette())
   

   for lp =0 to 15
         palette(lp) =rndrgb()
   next

   Palette(0)  = $0000ff
   Palette(1)  = $ffffff
   


   constant ScreenWidth = 320
   constant ScreenHeight = 200

   PaletteSCreenImage=GetFreeImage()      
   CreateFXImageEx PaletteScreenImage,ScreenWidth,ScreenHeight, 16
   
   FxScreen   = newfximage(SCreenWidth,ScreenHeight)
   
   

   x1=rnd(ScreenWidth)
   y1=rnd(ScreenHeight)


do   
   rendertoimage PaletteScreenImage


   x2=rnd(ScreenWidth)
   y2=rnd(ScreenHeight)
   
   linec x1,y1,x2,y2,indextorgb(rnd(15))

   circlec mousex(),mousey(),30,true, indextorgb(CurrentColour)

   if mousebutton()=1 and ButtonDown=false
      CurrentColour = (CurrentColour+1 ) and $f      
      ButtonDown=true
   else
      ButtonDown=false
   endif


   x1=x2
   y1=y2
   
   RenderPaletteMappedScreen(PaletteScreenImage,0,0,FxScreen)

   rendertoscreen   
   
   drawrotatedimage  FxScreen,0,0,0,2,2,0,0,false
      
   drawimage PaletteScreenImage,400,0,false
   
   sync

loop spacekey()
end
   


function RenderPaletteMappedScreen(SrcPalettedImage,Xpos,Ypos,DestImage=0)
   
   if GetImageDepth(SrcPalettedImage) = 16

      local OldSurface = getSurface()
   
      rendertoimage DestImage   
         
         lockbuffer
         local ThisRGB       = point(0,0)
         local ImagePtr    = GetImagePtr(SrcPalettedImage)
         local ImageModulo = GetImagePitch(SrcPalettedImage)
         
         local Width = GetImageWidth(SrcPalettedImage)
         
         For ylp=0 to GetImageHeight(SrcPalettedImage)-1
               DrawPaletteMappedStrip16 Xpos, Ypos+ylp, ImagePtr, Width, $000f   
               ImagePtr+=ImageModulo
         next
   
         unlockbuffer   

      rendertoimage OldSurface
   endif
EndFunction

   
[/pbcode]

Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: baggey on January 26, 2018, 12:58:52 PM
Quote from: kevin on November 22, 2017, 09:12:17 AM

PlayBASIC LIVE:   How to Make a 320 by 200 16 colour Palette Mapped Screen  (22 Nov 2017)

   In this video we take a look at how we could use the Palette mapping library to create a classic 8 bit styled screen that's 320 by 200 pixels with only 16 colours.    Which is something like the  type of graphic hardware you'd find in that classic 8bit / 16 bit computers.  In this example the programmer can use any of the 16 colours anyway on the the screen at any time,  this was generally not the case for classic  8Bit systems, which tend to have various limitations on how many colours can appears within a bitmap,  which makes some of the old artists even more impressive. 

Anyway, you can find the source code on our forums of course with thousands of other examples..  Have fun !

Video:


Example Code:
[pbcode]

// Include the palette Mapping library
   #include "paletteMapping"
   

   // Define    
   Dim Palette(256)
   
   
   SetPalette(Palette())
   

   for lp =0 to 15
         palette(lp) =rndrgb()
   next

   Palette(0)  = $0000ff
   Palette(1)  = $ffffff
   


   constant ScreenWidth = 320
   constant ScreenHeight = 200

   PaletteSCreenImage=GetFreeImage()      
   CreateFXImageEx PaletteScreenImage,ScreenWidth,ScreenHeight, 16
   
   FxScreen   = newfximage(SCreenWidth,ScreenHeight)
   
   

   x1=rnd(ScreenWidth)
   y1=rnd(ScreenHeight)


do   
   rendertoimage PaletteScreenImage


   x2=rnd(ScreenWidth)
   y2=rnd(ScreenHeight)
   
   linec x1,y1,x2,y2,indextorgb(rnd(15))

   circlec mousex(),mousey(),30,true, indextorgb(CurrentColour)

   if mousebutton()=1 and ButtonDown=false
      CurrentColour = (CurrentColour+1 ) and $f      
      ButtonDown=true
   else
      ButtonDown=false
   endif


   x1=x2
   y1=y2
   
   RenderPaletteMappedScreen(PaletteScreenImage,0,0,FxScreen)

   rendertoscreen   
   
   drawrotatedimage  FxScreen,0,0,0,2,2,0,0,false
      
   drawimage PaletteScreenImage,400,0,false
   
   sync

loop spacekey()
end
   


function RenderPaletteMappedScreen(SrcPalettedImage,Xpos,Ypos,DestImage=0)
   
   if GetImageDepth(SrcPalettedImage) = 16

      local OldSurface = getSurface()
   
      rendertoimage DestImage   
         
         lockbuffer
         local ThisRGB       = point(0,0)
         local ImagePtr    = GetImagePtr(SrcPalettedImage)
         local ImageModulo = GetImagePitch(SrcPalettedImage)
         
         local Width = GetImageWidth(SrcPalettedImage)
         
         For ylp=0 to GetImageHeight(SrcPalettedImage)-1
               DrawPaletteMappedStrip16 Xpos, Ypos+ylp, ImagePtr, Width, $000f   
               ImagePtr+=ImageModulo
         next
   
         unlockbuffer   

      rendertoimage OldSurface
   endif
EndFunction

   
[/pbcode]


How do i get the library and install it?
Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: baggey on January 27, 2018, 01:18:41 AM
Okay, I just jumped to code and saw library.
Watched the video absoloutly superb!

Would love to see a video of making a program thats slow say bit banging pixels on screen and the compiling and converting with the machine code tool!

Kind Regards Baggey ;D
Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: kevin on January 29, 2018, 10:59:21 AM

Quote
Would love to see a video of making a program thats slow say bit banging pixels on screen and the compiling and converting with the machine code tool!

  Yep that's on the TO DO list..
Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: baggey on May 25, 2018, 02:35:57 PM
Hi,

Ive modified the code abit. I can't get fastdot to work? but dotc does?
I need to make this full screen or no window streched!
Heres the code.

Example Code:
[pbcode]
; PROJECT : zx81

; CREATED : 25/05/2018
; ---------------------------------------------------------------------

// Include the palette Mapping library
   #include "paletteMapping"
   openscreen 256,192,16,2

   // Define   
   Dim Palette(256)
   dim inkindex(15)
   
   SetPalette(inkindex())
   

  ; for lp =0 to 15
   ;      inkindex(lp) =rndrgb()
   ;next
initColorArrays()

  ;inkindex(0)  = $0000ff
  ; inkindex(1)  = $ffffff
   


   constant ScreenWidth = 256
   constant ScreenHeight = 192

   PaletteSCreenImage=GetFreeImage()     
   CreateFXImageEx PaletteScreenImage,ScreenWidth,ScreenHeight, 16
   
   FxScreen   = newfximage(SCreenWidth,ScreenHeight)
   
   

;  x1=rnd(ScreenWidth)
  ; y1=rnd(ScreenHeight)


do   
   ;rendertoimage PaletteScreenImage

rendertoimage PaletteScreenImage
    lockbuffer
   for x= 0 to 256
      for y= 0 to 192
         ;fastdot x,y,palette((rnd(15)))
         dotc x,y,inkindex(rnd(15))
         next
         next
   
   unlockbuffer
   
   RenderPaletteMappedScreen(PaletteScreenImage,0,0,FxScreen)

   rendertoscreen   
   
   drawrotatedimage  FxScreen,0,0,0,10,10,0,0,false
 
   
   ;drawimage PaletteScreenImage,400,0,false
   
   sync

loop spacekey()
end
   


function RenderPaletteMappedScreen(SrcPalettedImage,Xpos,Ypos,DestImage=0)
   
   if GetImageDepth(SrcPalettedImage) = 16

      local OldSurface = getSurface()
   
      rendertoimage DestImage   
         
         lockbuffer
         local ThisRGB       = point(0,0)
         local ImagePtr    = GetImagePtr(SrcPalettedImage)
         local ImageModulo = GetImagePitch(SrcPalettedImage)
         
         local Width = GetImageWidth(SrcPalettedImage)
         
         For ylp=0 to GetImageHeight(SrcPalettedImage)-1
               DrawPaletteMappedStrip16 Xpos, Ypos+ylp, ImagePtr, Width, $000f   
               ImagePtr+=ImageModulo
         next
   
         unlockbuffer   

      rendertoimage OldSurface
   endif
EndFunction


PSub InitColorArrays()
   
// Ive set the colors up here in RGB but using the palletindex(0)
// We have standard colors so we can make our own pallets!
// select color

// Standard Spectrum colors

   // Normal
      inkindex(0) = $0000ff ;rgb(0, 0, 0); Black
      inkindex(1) = rgb(0,0,192); Blue
      inkindex(2) = rgb(192,0,0); Red   
      inkindex(3) = rgb(192,0,192); Magenta
      inkindex(4) = rgb(0,192,0); Green
      inkindex(5) = rgb(0,192,192); Cyan
       inkindex(6) = rgb(192,192,0); Yellow
      inkindex(7) = rgb(192,192,192); White

   // Bright
      inkindex(8)  = rgb(0, 0, 0); Black
      inkindex(9)  = rgb(0,0,255); Blue
      inkindex(10) = rgb(255,0,0); Red   
      inkindex(11) = rgb(255,0,255); Magenta
      inkindex(12) = rgb(0,255,0); Green
      inkindex(13) = rgb(0,255,255); Cyan
       inkindex(14) = rgb(255,255,0); Yellow
      inkindex(15) = rgb(255,255,255); White

EndpSub
[/pbcode]
Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: kevin on May 26, 2018, 10:18:04 AM


this loop has a couple of errors in it

[pbcode]

rendertoimage PaletteScreenImage
    lockbuffer
   for x= 0 to 256
      for y= 0 to 192
         ;fastdot x,y,palette((rnd(15)))
         dotc x,y,inkindex(rnd(15))
         next
         next
   
   unlockbuffer
[/pbcode]



   Any of the FAST named commands such FastDot / FastPoint (and a few others) others require the surface to pre-seeded prior to calling.   These commands dont have any of them built into them, nor do they generally have clipping..   You can do this via using the DOT/POINT() commands on them.  Generally it's gest to use POINT as it doesn't change the surface.

Quote
      Note: Before you can use FastDot correctly. After you lock the draw surface, it's highly recommended you read a pixel from this surface using Point(). This will ensure the address of the surface is seeded for FASTDOT and FastPoint.



  so it should be

[pbcode]

rendertoimage PaletteScreenImage
    lockbuffer
    ThisRGB=Point(0,0) ; read a null pixel to make sure the current surface is seeded..

   for x= 0 to 256
      for y= 0 to 192
            fastdot x,y,inkindex(rnd(15))
         next
   next
   
   unlockbuffer
[/pbcode]


   not sure if know this but if the image it's drawing onto is 256 * 192 then the previous loops are writinf outside of the image memory, as Image sizes are Inclusive / Exclusive so pixels on the X axis range from 0 to 255 and the same for the Y axis.

[pbcode]

rendertoimage PaletteScreenImage
    lockbuffer
    ThisRGB=Point(0,0) ; read a null pixel to make sure the current surface is seeded..

   for x= 0 to 256-1
      for y= 0 to 192-1
            fastdot x,y,inkindex(rnd(15))
         next
   next
   
   unlockbuffer
[/pbcode]






Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: baggey on May 29, 2018, 01:41:09 AM
Hi Again,

Im trying to understand this Palette buffer Stuff and struggling. I see Direct buffer writing is FAST!
So If we have a palette screen. We need the Pallette reference to set the colour of the Pixel Sprite part in memory.

I get the part were we find the address pointer of the colour part of the image and work down in a timely fashon from left to right.
So in a 8bit screen the pitch is one Byte. So the number it can hold is 255. This is linked to the Pallette map index. This holeds the index to the RGB(value)

In my code for some reason only inkindex(0) is working!!? I can't get the rnd selection to work is this something to do with GLOBAL variables.

Or does the Pallette Mapper routine not see my Dim array for some reason?

Baggey

Example Code:
[pbcode]
; PROJECT : Project2
; AUTHOR  : Microsoft
; CREATED : 29/05/2018
; ---------------------------------------------------------------------

; PROJECT : zx81

; CREATED : 25/05/2018
; ---------------------------------------------------------------------

// Include the palette Mapping library
  #include "paletteMapping"
  openscreen 256,192,16,2

  // Define    
  Dim Palette(256)
  dim inkindex(15)
 
  SetPalette(inkindex())
   initColorArrays()

 ;inkindex(0)  = $0000ff
  inkindex(10)  = $ff0000
 


  constant ScreenWidth = 256
  constant ScreenHeight = 192

  PaletteSCreenImage=GetFreeImage()      
  CreateFXImageEx PaletteScreenImage,ScreenWidth,ScreenHeight, 16
 
  FxScreen   = newfximage(SCreenWidth,ScreenHeight)

  do  
 
   rendertoimage PaletteScreenImage
   lockbuffer
   ThisRGB=Point(0,0) ; read a null pixel to make sure the current surface is seeded..

  for x= 0 to 256-1
     for y= 0 to 192-1
           fastdot x,y,inkindex(rnd(15))
        next
  next
 
  unlockbuffer
 
  RenderPaletteMappedScreen(PaletteScreenImage,0,0,FxScreen)

  rendertoscreen  
 
  drawrotatedimage  FxScreen,0,0,0,4,4,0,0,false
 
  sync

   loop spacekey()
   end
   


function RenderPaletteMappedScreen(SrcPalettedImage,Xpos,Ypos,DestImage=0)
 
  if GetImageDepth(SrcPalettedImage) = 16

     local OldSurface = getSurface()
 
     rendertoimage DestImage  
       
        lockbuffer
        local ThisRGB       = point(0,0)
        local ImagePtr    = GetImagePtr(SrcPalettedImage)
        local ImageModulo = GetImagePitch(SrcPalettedImage)
       
        local Width = GetImageWidth(SrcPalettedImage)
       
        For ylp=0 to GetImageHeight(SrcPalettedImage)-1
              DrawPaletteMappedStrip16 Xpos, Ypos+ylp, ImagePtr, Width, $000f  
              ImagePtr+=ImageModulo
        next
 
        unlockbuffer  

     rendertoimage OldSurface
  endif
EndFunction


PSub InitColorArrays()
 
// Ive set the colors up here in RGB but using the palletindex(0)
// We have standard colors so we can make our own pallets!
// select color

// Standard Spectrum colors

  // Normal
     inkindex(0) = rgb(0,192,192) ;rgb(0, 0, 0); Black
     inkindex(1) = rgb(0,0,192); Blue
     inkindex(2) = rgb(192,0,0); Red  
      inkindex(3) = rgb(192,0,192); Magenta
      inkindex(4) = rgb(0,192,0); Green
     inkindex(5) = rgb(0,192,192); Cyan
      inkindex(6) = rgb(192,192,0); Yellow
     inkindex(7) = rgb(192,192,192); White

  // Bright
      inkindex(8)  = rgb(0, 0, 0); Black
     inkindex(9)  = rgb(0,0,255); Blue
     inkindex(10) = rgb(255,0,0); Red  
      inkindex(11) = rgb(255,0,255); Magenta
      inkindex(12) = rgb(0,255,0); Green
     inkindex(13) = rgb(0,255,255); Cyan
      inkindex(14) = rgb(255,255,0); Yellow
     inkindex(15) = rgb(255,255,255); White

EndpSub
[/pbcode]

So yeah ive done some messing around and have changed the command fastdot for this line of code.


Example Code:
[pbcode]
fastdot x,y,rgb(rnd(255),rnd(255),rnd(255))
[/pbcode]

Im now getting random colours. Ive made a schoolboy error somewhere or theres some other reason?

Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: kevin on May 29, 2018, 10:54:36 AM

if want to use DOT/FASTDOT/ LINE / BOX etc etc on surface your going to render with a palette,  then check out the help files ->Palette Mapping -> IndexRoRGB  and RGBtoIndex

[pbcode]


// Include the palette Mapping library
   #include "paletteMapping"
   openscreen 256,192,16,2

   // Define   
   dim inkindex(15)
   
   initColorArrays()

   SetPalette(inkindex())



   constant ScreenWidth = 256
   constant ScreenHeight = 192

   PaletteSCreenImage=GetFreeImage()     
   CreateFXImageEx PaletteScreenImage,ScreenWidth,ScreenHeight, 16
   
   FxScreen   = newfximage(SCreenWidth,ScreenHeight)

   do   
   
    rendertoimage PaletteScreenImage
    lockbuffer
       ThisRGB=Point(0,0) ; read a null pixel to make sure the current surface is seeded..
          for y= 0 to 192-1
                ; do rows by cols since that's how image memory is laid out
           for x= 0 to 256-1

                  ; FastDOT renders RGB's so in order to write an INDEX
                  ; it first needs to be converted to a RGB colour, others bits will be lost.
                  ; Ie.  All drawing assumed 32bit RGB, the lower 3 bits don't exist when drawing
                  ; to a 16bit 565 / 555 surface
                 FastDot x,y,IndexToRGB(rnd(15))
            next
        next
   unlockbuffer
   
   RenderPaletteMappedScreen(PaletteScreenImage,0,0,FxScreen)

   rendertoscreen   
   
   drawrotatedimage  FxScreen,0,0,0,4,4,0,0,false
 
   sync

   loop spacekey()
    end
   


function RenderPaletteMappedScreen(SrcPalettedImage,Xpos,Ypos,DestImage=0)
   
   if GetImageDepth(SrcPalettedImage) = 16

      local OldSurface = getSurface()
   
      rendertoimage DestImage   
         
         lockbuffer
         local ThisRGB       = point(0,0)
         local ImagePtr    = GetImagePtr(SrcPalettedImage)
         local ImageModulo = GetImagePitch(SrcPalettedImage)
         
         local Width = GetImageWidth(SrcPalettedImage)
         
         For ylp=0 to GetImageHeight(SrcPalettedImage)-1
               DrawPaletteMappedStrip16 Xpos, Ypos+ylp, ImagePtr, Width, $000f   
               ImagePtr+=ImageModulo
         next
   
         unlockbuffer   

      rendertoimage OldSurface
   endif
EndFunction


PSub InitColorArrays()
   
// Ive set the colors up here in RGB but using the palletindex(0)
// We have standard colors so we can make our own pallets!
// select color

// Standard Spectrum colors

   // Normal
      inkindex(0) = rgb(0,192,192) ;rgb(0, 0, 0); Black
      inkindex(1) = rgb(0,0,192); Blue
      inkindex(2) = rgb(192,0,0); Red   
       inkindex(3) = rgb(192,0,192); Magenta
       inkindex(4) = rgb(0,192,0); Green
      inkindex(5) = rgb(0,192,192); Cyan
       inkindex(6) = rgb(192,192,0); Yellow
      inkindex(7) = rgb(192,192,192); White

   // Bright
       inkindex(8)  = rgb(0, 0, 0); Black
      inkindex(9)  = rgb(0,0,255); Blue
      inkindex(10) = rgb(255,0,0); Red   
       inkindex(11) = rgb(255,0,255); Magenta
       inkindex(12) = rgb(0,255,0); Green
      inkindex(13) = rgb(0,255,255); Cyan
       inkindex(14) = rgb(255,255,0); Yellow
      inkindex(15) = rgb(255,255,255); White

EndpSub

[/pbcode]


    You can of course just poke the Bytes/ Words in directly into the image,  get pointer to the surface and pitch/modulo, then compute the addres of the dot and write to memory (PokeByte / PokeWord)

Title: Re: PlayBASIC LIVE: How to Make a 320 by 200 16 colour Palette Mapped Screen
Post by: baggey on May 29, 2018, 12:42:20 PM
If only i new how to program well!