Menu

Ili9341 readpixel demo game

2020-03-11
2020-03-19
  • stan cartwright

    stan cartwright - 2020-03-11

    I did a poor lunar lander to demo the ili9341 read_pixel function.
    It is a useful function but the demo only applies to ili9341 but is commented for pic or uno. I chose uno.
    The code checks the 4 corners of the sprite which are black against the background. If a corner is not black then it is the landscape.. test next sprite x,y before drawing.
    Also the sprite has black pixels around it so it does not need erasing before it's redrawn as it erases itself when redrawn as it only moves 1 pixel at a time.
    The game was supposed to have inertia but I got bored...and I didn't debounce the buttons either.
    It has a fuel bar..no fuel..no thrust. Change to 1000 to make it harder or redraw the landscape.
    I even used goto as it seemed so elegant and simple. Structured is hard.
    https://www.youtube.com/watch?v=SGJFApFqx1Q

    ;ili9341 ReadPixel_ILI9341 test for pic and avr 328p
    ;#chip 18f25k22,64
    ;#config MCLRE=on
    ;#option Explicit
    ;#include <glcd.h>
    
    ;#define GLCD_TYPE GLCD_TYPE_ILI9341
    
    'Pin mappings for ILI9341
    ;#define GLCD_DC portc.2
    ;#define GLCD_CS portc.0
    ;#define GLCD_RESET portc.1
    
    'As we are using Harware SPI this cannot be change on this chip. This is a non-PPS chip.
    ;#define GLCD_DI portc.4
    ;#define GLCD_DO portc.5
    ;#define GLCD_SCK portc.3
    ;#define ILI9341_hardwarespi
    
    
    ;this 328p setup
    #chip mega328p,16
    #include <glcd.h>
    #option explicit
    ;--------------
    #define GLCD_TYPE GLCD_TYPE_ILI9341
    
    #define GLCD_DC      portb.0 ;   DIGITAL_8           ' Data command line
    #define GLCD_CS      portb.2 ;   DIGITAL_10          ' Chip select line
    #define GLCD_RESET   portb.1 ;   DIGITAL_9           ' Reset line
    #define GLCD_DI      portb.4 ;   DIGITAL_12          ' Data in | MISO    - Not used therefore not really required
    #define GLCD_DO      portb.3 ;   DIGITAL_11          ' Data out | MOSI
    #define GLCD_SCK     portb.5 ;   DIGITAL_13          ' Clock Line
    
    #define ILI9341_HardwareSPI    ' remove/comment out if you want to use software SPI.
    
    ;rename colours to make less typeing
    #define bk ILI9341_BLACK
    #define re ILI9341_RED
    #define gr ILI9341_GREEN
    #define bl ILI9341_BLUE
    #define wh ILI9341_WHITE
    #define pu ILI9341_PURPLE
    #define ye ILI9341_YELLOW
    #define cy ILI9341_CYAN
    #define dg ILI9341_D_GRAY
    #define lg ILI9341_L_GRAY
    #define si ILI9341_SILVER
    #define ma ILI9341_MAROON
    #define ol ILI9341_OLIVE
    #define li ILI9341_LIME
    #define aq ILI9341_AQUA
    #define te ILI9341_TEAL
    #define na ILI9341_NAVY
    #define fu ILI9341_FUCHSIA
    
    #define GLCD_EXTENDEDFONTSET1
    
    ;pic button ports, all buttons held hi by 10k resistors
    ;#define left_thrust_button portb.5
    ;#define vertical_thrust_button portb.4
    ;#define right_thrust_button portb.3
    
    ;uno button ports, all buttons held hi by 10k resistors
    #define left_thrust_button portc.0
    #define vertical_thrust_button portc.1
    #define right_thrust_button portc.2
    
    dir left_thrust_button in
    dir vertical_thrust_button in
    dir right_thrust_button in
    ;
    dim temp as Byte
    dim pixel_colour_left_top,pixel_colour_right_top,pixel_colour_left_bottom,pixel_colour_right_bottom as long ;test pixel colour
    dim ,sprite_height,sprite_width as byte ;height and width of sprite in pixels
    dim sprite_x,sprite_y as Word ;xy position of sprite
    dim ptr,spritedata_ptr,pixel,x_dir,fuel as word
    dim gravity,gravity_count,x_drift as Byte
    ;
    start:
    wait 5 s
    GLCDRotate ( Portrait )  ;xy=0 top left,
    ;optionally you can rotate the screen.GLCDRotate ( Portrait_Rev )
    GLCDCLS bk ;black background
    
    fuel = 1400
    sprite_x=120:sprite_y=40 ; sprite x,y start
    sprite_height=24:sprite_width=24
    gravity_count=20
    x_drift = 20
    x_dir = 0
    ;
    ;draw lanscape
    line 0,16,16,80,wh
    line 16,80,48,100,wh
    line 48,100,30,200,wh
    line 30,200,40,210,wh
    line 40,210,50,290,wh
    line 50,290,200,319,wh
    
    line 200,319,230,319,wh
    
    line 230,319,230,290,wh
    line 230,290,210,240,wh
    line 210,240,120,230,wh
    line 120,230,120,200,wh
    line 120,200,220,210,wh
    line 220,210,239,16,wh
    
    GLCDfntDefaultsize = 2
    GLCDPrint 0,0,"FUEL"
    line 60,8,fuel/10,8,wh
    ;sprite (sprite_x,sprite_y) ;draw sprite
    ;----------------------------------
    do ;main loop
    
    pset 60+(fuel / 10),8,bk
    
    pixel_colour_left_bottom = ReadPixel_ILI9341(sprite_x ,sprite_y + 23) and 0xfffff ;left bottom pixel colour
    pixel_colour_right_bottom =  ReadPixel_ILI9341(sprite_x + 23,sprite_y + 23) and 0xfffff ;right bottom pixel colour
    pixel_colour_left_top = ReadPixel_ILI9341(sprite_x ,sprite_y) and 0xfffff ;left top pixel colour
    pixel_colour_right_top =  ReadPixel_ILI9341(sprite_x + 23,sprite_y) and 0xfffff ;right top pixel colour
    
    if pixel_colour_left_bottom > 0 then
      if  pixel_colour_right_bottom > 0 then ;both pixels lit so flat
        GLCDPrint 70,100,"LANDED",wh
        goto start
      end if
    end if
    
    if pixel_colour_left_top > 0 then
      crashed
      GLCDPrint 40,100,"top left",wh
      goto start
    end if
    
    if pixel_colour_right_top > 0 then
      crashed
      GLCDPrint 40,100,"top right",wh
      goto start
    end if
    
    if pixel_colour_left_bottom > 0 then
      crashed
      GLCDPrint 40,100,"left bottom",wh ;hit left bottom
      goto start
    end if
    
    if pixel_colour_right_bottom > 0 then
      crashed
      GLCDPrint 40,100,"right bottom",wh ;hit right bottom
      goto start
    end if
    
    gravity_count = gravity_count + 1
    
    if fuel > 2 then
      if vertical_thrust_button=0 then
        gravity_count = gravity_count - 2
        flame
        fuel = fuel - 2
      end if
    
      if left_thrust_button=0 then
        flame
        fuel = fuel - 1
        x_drift = x_drift + 1
      else if right_thrust_button = 0 then
        flame
        fuel = fuel - 1
        x_drift = x_drift - 1
      end if
    end if
    ;
    if x_drift = 15 then
      x_drift = 20
      x_dir = 65535
      sprite_x = sprite_x + x_dir
    else if x_drift = 25 then
      x_drift = 20
      x_dir = 1
      sprite_x = sprite_x + x_dir
    end if
    
    sprite (sprite_x,sprite_y) ;draw sprite
    
    ;
    if gravity_count=15 then
      gravity_count=20
      sprite_y = sprite_y - 1
    else if gravity_count = 25 then
      gravity_count=20
      sprite_y = sprite_y + 1
    end if
    
    if sprite_y < 30 then sprite_y = 30
    
    loop
    ;----------------------------------
    sub sprite (sprite_x,sprite_y) ;fills box with sprite data
    ;  SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x + sprite_width-1,sprite_y + sprite_height - 1 )
      SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x + 23,sprite_y + 23)
      for ptr=1 to 576 ;(sprite_width * sprite_height)
        ReadTable lander,ptr,pixel
        SendWord_ILI9341 pixel
      next ptr
    end sub
    ;
    sub flame
      line sprite_x+6,sprite_y+12,sprite_x+11,sprite_y+21,wh
      line sprite_x+16,sprite_y+12,sprite_x+13,sprite_y+21,wh
    end sub
    ;
    sub crashed
      for ptr = 1 to 20
        circle sprite_x + 11,sprite_Y + 11, ptr, wh
        wait 100 ms
      next ptr
    
      for ptr = 1 to 20
        circle sprite_x + 11,sprite_Y + 11, ptr, bk
        wait 100 ms
      next ptr
    end sub
    ;
    ;sprite data
    ;1 2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 21 23 24
    table lander
    bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk ;1
    bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,wh,wh,wh,wh,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk ;2
    bk,bk,bk,bk,bk,bk,bk,wh,wh,bk,bk,bk,bk,bk,bk,wh,wh,bk,bk,bk,bk,bk,bk,bk ;3
    bk,bk,bk,bk,bk,bk,wh,bk,bk,bk,wh,wh,wh,wh,bk,bk,bk,wh,bk,bk,bk,bk,bk,bk ;4
    bk,bk,bk,bk,wh,wh,bk,bk,wh,wh,bk,bk,bk,bk,wh,wh,bk,bk,wh,wh,bk,bk,bk,bk ;5
    bk,bk,bk,wh,bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk,wh,bk,bk,bk ;6
    bk,bk,wh,bk,bk,wh,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,wh,bk,bk,wh,bk,bk ;7
    bk,bk,wh,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,wh,bk,bk ;8
    bk,bk,bk,wh,bk,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,bk,wh,bk,bk,bk ;9
    bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk ;10
    bk,bk,bk,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,bk,bk,bk ;11
    bk,bk,bk,bk,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,wh,bk,bk,bk,bk ;12
    bk,bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk,bk ;13
    bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk ;14
    bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk ;15
    bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk ;16
    bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk ;17
    bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk ;18
    bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk ;19
    bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk ;20
    bk,bk,bk,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,bk,bk,bk ;21
    bk,bk,wh,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,wh,bk,bk ;22
    bk,wh,wh,wh,wh,wh,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,wh,wh,wh,wh,wh,bk ;23
    bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk ;24
    end table
    ;
    
     

    Last edit: stan cartwright 2020-03-11
  • mkstevo

    mkstevo - 2020-03-13

    As Brucie might have said... Good game, good game!

    Well done, I like that.

     
    • stan cartwright

      stan cartwright - 2020-03-14

      Cheers. It was supposed to help others using ili9341, which Evan has put much work into.
      His demo, though practical doesn't inspire you. I hoped this would.
      Maybe glcd games is not what pics were meant for as there are better alternatives but once the hardware is set up, it's fun.
      Checking a line is lit can lead to it not actually being lit as lines are made of pixels and not pixels and a condition can occur when it scans a pixel on a line and it's not lit and the next position is not lit.so it misses it.
      I was gonna write the land scape to a table, draw it once then offset it x+1.y+1 and draw it again so the landscape was thicker.
      Plenty to play with and enjoy the ili9341. h.
      Missile command would be easy..ish

       
  • stan cartwright

    stan cartwright - 2020-03-15

    I am wondering if 80's style 3d graphics would be possible. The trig functions are there.

     
  • stan cartwright

    stan cartwright - 2020-03-15

    I am wondering if 80's style 3d graphics would be possible. The trig functions are there.
    Credit to Evan for the ili9341 include and features.
    i got another glcd display that Evan has supported,uses 8 pin data and other clock etc. but don't run that much faster than using spi really it seems....side by side comparison needed.

     
    • Anobium

      Anobium - 2020-03-16

      Cheers.

      PACMAN first surely?

      Re 3d Graphics. I would be using a table to draw the 3D effects, The maths of the TRIG ops could be very slow. As you can only have a limited number of rotational positions for the 'object' you could put all the possible data into a table... But, I would test both methods.

      Re SPI, 8Bit performance. It all depends. There are many parameters that impact performance but a full port (NOT AN UNO which does two write per byte) would be fastest.

       
      • stan cartwright

        stan cartwright - 2020-03-16

        I think pacman would involve a lot more than you'd think. Those old sinclair Z80 games were quite good for the hardware they had ie non but they worked by knowing the screen memory, which was refreshed regularly. No AYxxx sound chip and no graphic acceration, which the commode 64 did have and 6502 asm was simpler than Z80 but the Z80 had commands like LDIR which speeded code up.

         
      • stan cartwright

        stan cartwright - 2020-03-16

        Re 3d graphics.
        yes a table of pre defined 3D graphics would be better for drawing shapes.
        Maybe no trig to define the data, just a win prog that rotates a shape and scales it.
        The scaleing function might be useful depending how fast it is.
        Calculations between frames slow graphics display.
        Using a tiny ssd oled with the display as 1K ram is a nicer model to work on but it's so tiny!!
        You can mess with screen ram in theory directly. The include is a bit hackable if you want to, again another Evan effort to create an include. Who else would have?

         
        • Anobium

          Anobium - 2020-03-17

          A thoughts regarding the calc timing between frames. Why not test using an interrupt to update the frames every 1/25th of second. Then you may have time to do the calcs - try on on a working solution like the lander.

           
  • stan cartwright

    stan cartwright - 2020-03-17

    I remember Elite for the BBC micro, which was too expensive for me. It was released on spectrum later. Apparently it's done with matrices which are like arrays of data. I remember being asked to write for the Electron micro but it used an ULA like the Spectrum and was much slower than BBC micro, using the same code...10X slower.
    Amstrad 464 was z80 but it had pallette switching meaning you could draw different shapes in different colours and animate by changing the colour values even though they were all on screen at once. https://www.youtube.com/watch?v=AuvbZpH1QuE

     

    Last edit: stan cartwright 2020-03-17
  • Anobium

    Anobium - 2020-03-17

    Anything is possible.... I remember Elite.

     
    • stan cartwright

      stan cartwright - 2020-03-18

      Probably on a bbc puter which was nice hardware and well documented.
      Spectrum we sort of worked how it worked but the hardware was totally different, ie non.
      but the z80 pissed all over a 6502 :)
      would supporting AY-3-8910 be interesting or has been done or are better chips to use?

      https://www.youtube.com/watch?v=GpWoF5uVgbA

       

      Last edit: stan cartwright 2020-03-18
  • stan cartwright

    stan cartwright - 2020-03-18

    I do not know the 3d stuff that can be done with gcb. An illusion with lines and going left right and forward I will test but will be too slow I think without palette switching ie re drawing and erasing stuff

    The ili displays were cheap and gcb does a good job of supporting them.
    Pity about 3.3V logic levels. Apart from that very nice and more interesting than mono 2 line displays...which if you had the method could do crude graphics. I got a psion 2 line hand held thing some where that you can program...yawn

    Using a pic at 3.3V is a simple hardware solution
    I don't know why I chose a uno and a logic level converter

    If you want to see what a pic/uno can do using #include <glcd.h> an ILI9341 is a nice display to play with.
    You could find the sprite code your self in the ili9341.h and see how the pixel read works.
    It's a fun display to play with and like most gcb progs quick to alter and see results</glcd.h>

     

    Last edit: stan cartwright 2020-03-18
  • stan cartwright

    stan cartwright - 2020-03-18

    The editor seems behaving strangely

     
  • stan cartwright

    stan cartwright - 2020-03-18

    I was up to 3.30 am searching for 3d graphic tutorials but they are mostly direct x and open gl, not old school. Anyway self isolating even though I feel ok...even after drinking Russian standard vodka cos I needed to relax. I get irate staying in. I can go into my garden but the rain has made it very wet and it's a pain to go to my shed and get the galllon of isopropanol to make hand cleanser. I don't keep much indoors as it's 99.5% and inflammable.
    Get back when I sort a matrix for a cube. Take care all.

     
  • stan cartwright

    stan cartwright - 2020-03-19

    I found this freebasic code for a rotating cube and will try converting it to gcb.
    lines like this will be hard but no trig. rx = -0.1 : rem rotation angle x
    http://retro64.altervista.org/ProgrammingExamples/Freebasic/3dcube_04.bas

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.