This is the simplest way to draw a multi coloured sprite I've found. It writes sprite height x width number of words to the display in a graphic window.
Problem is sprite data is stored in tables that can only be 256 items and that includes the 1st byte which holds the table size..from help.
A 16 x 16 pixel sprite is 256 words so as the last pixel is black a problem doesn't show. A square would show the problem but coloured thing looks more interesting.
To get over this table size problem I used two tables and as the sprite sub is only a few lines I copied it to use two tables....I know, sloppy but can't think of another solution other than copy table to array then use that..
It's quite fast visually but could be faster. https://www.youtube.com/watch?v=Wz8iw07ncqI&feature=youtu.be
Sorry,can't see add file so-
;ILI9341spritedemo#chip mega328p, 16#option explicit#include<glcd.h>;#define GLCD_TYPE GLCD_TYPE_ILI9341#define GLCD_DC portb.2#define GLCD_CS portd.7#define GLCD_RESET portd.4#define GLCD_DO portb.3 ; MOSI SDI#define GLCD_SCK portb.5 ; SCK#define ILI9341_HardwareSPI#define GLCD_EXTENDEDFONTSET1;;nowrenamecolourstomakeiteasiertosetupspritedata#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;GLCDBackground=ILI9341_BLACKGLCDRotatePortrait_RevGLCDCLSILI9341_BLACK;dimsprite_height,sprite_widthasbyte;heightandwidthofspriteinpixels;dimspritedataasbyte;datatomakespritedimsprite_x,sprite_yasWorddimptr,spritedata_ptr,pixelasword;;demovarsdimtemp,frameasbytedimdx(8),dy(8)asworddimspy(8),oldspy(8)asworddimspx(8),oldspx(8)asword;setupstartspritepositionsanddirectionsdx(1)=2:dx(2)=3:dx(3)=65536-4:dx(4)=6dx(5)=65536-8:dx(6)=65536-8:dx(7)=65536-8:dx(8)=65536-8dy(1)=65536-5:dy(2)=65536-3:dy(3)=65536-8:dy(4)=3dy(5)=2:dy(6)=7:dy(7)=2:dy(8)=8spx(1)=30:spx(2)=100:spx(3)=150:spx(4)=50spx(5)=160:spx(6)=100:spx(7)=80:spx(8)=30spy(1)=20:spy(2)=20:spy(3)=16:spy(4)=50:spy(5)=60:spy(6)=40spy(5)=20:spy(6)=30:spy(7)=24:spy(8)=36sprite_height=16:sprite_width=16spritedata_ptr=0frame=0;do;demomovingspritefortemp=1to8ifspx(temp)>(229-sprite_width)then;checkrightedgedx(temp)=65536-dx(temp)endififspx(temp)<8then;checkleftedgedx(temp)=65536-dx(temp)endififspy(temp)>(319-sprite_height)then;checkbottomedgedy(temp)=65536-dy(temp)endififspy(temp)<8then;checktopedgedy(temp)=65536-dy(temp)endif;oldspx(temp)=spx(temp):oldspy(temp)=spy(temp);getlastpositionforerasespx(temp)=spx(temp)+dx(temp):spy(temp)=spy(temp)+dy(temp);getnewpositionfordraw;ifframe=0thenerase_sprite(oldspx(temp),oldspy(temp));erasespriteatlastpositionsprite1(spx(temp),spy(temp));drawsprite1atnewpositionelseerase_sprite(oldspx(temp),oldspy(temp));erasespriteatlastpositionsprite2(spx(temp),spy(temp));drawsprite2atnewpositionendif;nexttempframe=!frame;wait20msloop;enddemo;subsprite1(sprite_x,sprite_y);fillsboxwithspritedataSetAddressWindow_ILI9341(sprite_x,sprite_y,sprite_x+15,sprite_y+15)forptr=1to256ReadTablespritedata1,ptr,pixelSendWord_ILI9341pixelnextptrendsub;subsprite2(sprite_x,sprite_y);fillsboxwithspritedataSetAddressWindow_ILI9341(sprite_x,sprite_y,sprite_x+15,sprite_y+15)forptr=1to256ReadTablespritedata2,ptr,pixelSendWord_ILI9341pixelnextptrendsub;suberase_sprite(sprite_x,sprite_y);writeaboxof0'sSetAddressWindow_ILI9341(sprite_x,sprite_y,sprite_x+15,sprite_y+15)repeat256SendWord_ILI93410endrepeatendsub;tablespritedata1bl,bl,bl,bl,bl,bk,bk,bk,bk,bk,bk,bl,bl,bl,bl,blbk,bl,re,re,re,bl,bl,bk,bk,bl,bl,re,re,re,bl,bkbk,bk,bl,re,re,re,bl,bk,bk,bl,re,re,re,bl,bk,bkbk,bk,bk,bl,re,wh,bl,bk,bk,bl,wh,re,bl,bk,bk,bkbk,bk,bk,bk,bl,wh,bl,bk,bk,bl,wh,bl,bk,bk,bk,bkbk,bk,bk,bk,bk,bl,bl,bk,bk,bl,bl,bk,bk,bk,bk,bkbk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bkbk,bk,bk,bk,ye,ye,ye,bk,bk,ye,ye,ye,bk,bk,bk,bkbk,bk,bk,ye,bk,bk,bk,bk,bk,bk,bk,bk,ye,bk,bk,bkbk,ye,ye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,ye,ye,bkbk,ye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,ye,bkye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,yeye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,yeye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,yebk,ye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,ye,bkbk,bk,ye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,ye,bk,bkendtable;tablespritedata2bl,bl,bl,bl,bl,bk,bk,bk,bk,bk,bk,bl,bl,bl,bl,blbk,bl,re,re,re,bl,bl,bk,bk,bl,bl,re,re,re,bl,bkbk,bk,bl,re,re,re,bl,bk,bk,bl,re,re,re,bl,bk,bkbk,bk,bk,bl,re,wh,bl,bk,bk,bl,wh,re,bl,bk,bk,bkbk,bk,bk,bk,bl,wh,bl,bk,bk,bl,wh,bl,bk,bk,bk,bkbk,bk,bk,bk,bk,bl,bl,bk,bk,bl,bl,bk,bk,bk,bk,bkbk,bk,bk,bk,bk,bk,bk,ye,ye,bk,bk,bk,bk,bk,bk,bkbk,bk,bk,bk,bk,ye,ye,bk,bk,ye,ye,bk,bk,bk,bk,bkbk,bk,bk,bk,ye,ye,bk,bk,bk,bk,ye,ye,bk,bk,bk,bkbk,bk,bk,bk,ye,bk,bk,bk,bk,bk,bk,ye,bk,bk,bk,bkbk,bk,bk,ye,bk,bk,bk,bk,bk,bk,bk,bk,ye,bk,bk,bkbk,bk,ye,bk,bk,bk,bk,bk,bk,bk,bk,bk,bk,ye,bk,bkbk,bk,bk,ye,ye,bk,bk,bk,bk,bk,bk,ye,ye,bk,bk,bkbk,bk,bk,bk,ye,ye,bk,bk,bk,bk,ye,ye,bk,bk,bk,bkbk,bk,bk,bk,bk,ye,bk,bk,bk,bk,ye,bk,bk,bk,bk,bkbk,bk,bk,bk,bk,bk,ye,bk,bk,ye,bk,bk,bk,bk,bk,bkendtable
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Can you check the code is complete and it works on cleanish installation? I get nothing on the screen. I have used the standard 'GLCD_Read_Demonstation_mega328p_for_ILI9341@16.gcb' as a compplete test and this works ok.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
From readtable help-
Item is 1 for the first line of the table, 2 for the second, and so on. Item 0 gives the size of the table. Care must be taken to ensure that the program is not told to read beyond the end of the table, or strange effects will be observed.
I tried using var sprite_ptr. Set to 1 read first sprite table. Set to 257 read second sprite table but didn't!
I can only read 256 of 512 items...words.Note I defined background pixels in table as black not 0 which is one byte as in my previous sprite code and two 12 x 12 sprites was 288 items was not a problem.
Please test readtable for table size.
sub sprite (sprite_x,sprite_y) ;fills box with sprite data
SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x +15,sprite_y +15 )
for ptr=sprite_ptr to sprite-ptr+256
ReadTable spritedata2,ptr,pixel
SendWord_ILI9341 pixel
next ptr
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In the code I posted I used dim ptr,spritedata_ptr,pixel as word to access table which was one big table not two. Setting ptr to 257 didn't read second table.
Please try to read both tables ie remove end table and table sprite_data2 so it's one 512 item table and please let me know. I'll try to do code to illustrate not more than 256 items. Hope it's an error on my part. Could you not just read a 1000 word table and ser print results to test.
Create one line and copy/paste to many,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I take it back.DOH moment.
I changed sprite sub to one sub and spritedata_ptr points to start of table or 257 items further and it works. This was my first effort that failed. Can't see what I've changed. Hmmmm...
sub sprite (sprite_x,sprite_y) ;fills box with sprite data
SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x +15,sprite_y +15 )
for ptr=spritedata_ptr to spritedata_ptr+256
ReadTable spritedata,ptr,pixel
SendWord_ILI9341 pixel
next ptr
end sub
and changed frame to animate between 2 sprites
if frame=0 then
erase_sprite (oldspx(temp),oldspy(temp)) ;erase sprite at last position
spritedata_ptr=1 :start of sprite one data
sprite (spx(temp),spy(temp)) ;draw sprite1 at new position
else
erase_sprite (oldspx(temp),oldspy(temp)) ;erase sprite at last position
spritedata_ptr=257 :start of sprite two data
sprite (spx(temp),spy(temp)) ;draw sprite2 at new position
end if
I can test. Is this complete working solution?
Did you sort the last byte in the sprite table?
And, we need to agree the standard ports for CS and DC. We are not using the same ports... with one of mine being the same as the Arduino library and your CS&DC neither match. If we aggree on a standard then I will change the demos to suit our new standard ports for CD&DC.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Fair,I changed ports for existing hardware.Posted more in the spirit, I thought it so simple so share.
I added a frame counter to "show" animation at end of demo. Only 2 frames but could be 3 or more.
I've attatched working code that uses "#include <UNO_mega328p.h>" and "DIGITAL_8" for gcb standard for arduino. Should plug play hope
video of code working https://youtu.be/YS2wjLmu4zA
frame_count++
if frame_count=5 then
frame=!frame
frame_count=0
end if
; wait 20 ms
loop ;end demo
Confused. Is this a change that needs be made to all the demos?
for ptr=spritedata_ptr to spritedata_ptr+255
Do I need to add?
I have remove Item 0 gives the size of the table. from the Help as this is not general rule and is clearly confusing.
And, to clarify. Great Cow BASIC table data starts at element 1. The Table handler will look after element Zero for you - so, as a general principle do not ever assume element Zero is the length.
You should use the following principe to ensure that you get it right all the time.
1. The first "item" in table is NOT the length of table.
2. A single value should be on each line
3. Byte, word, longs and integer values are valid (no strings or decimals!)
4. Multiple elements on a single line separated by commas but see item #2 above. A good practice is #2
5. Constants and calculations within the single line data table entries are permitted
6. You can use an external data source file as your table dataset.
7. To read a table of more than 256 elements you MUST you a WORD variable to address the element.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I re-attatched the last code posted, seems ok but I need a magnifier to see the sprite pixels.
It uses
#define GLCD_TYPE GLCD_TYPE_ILI9341
'Pin mappings for SPI - this GLCD driver supports Hardware SPI and Software SPI
#define GLCD_DC DIGITAL_8 ' Data command line
#define GLCD_CS DIGITAL_10 ' Chip select line
#define GLCD_RESET DIGITAL_9 ' Reset line
#define GLCD_DI DIGITAL_12 ' Data in | MISO - Not used therefore not really required
#define GLCD_DO DIGITAL_11 ' Data out | MOSI
#define GLCD_SCK DIGITAL_13 ' Clock Line
as in the glcd solutions if this is the standard gcb pins for uno.
As you hinted, using glcd window and writing words is faster than checking lit pixels and writing one word at a time. Also the erase is easy to.
Did the code run for you?
ps will miso be defined for read pixel routine?
I have adapted. Tiny improvements in passing paramers, background color change is now very easy, changing the framerate is now a constant (I like #define bg = teal), I have reverted to UNO Shield naming convension - all the other demos use this method.
If you want to review, and final tweaks, I would gladly publish as a demo.
I want to see the next part of the game when the touch one eats the another! One less.....
I'm implementing collision detection tests. I thought the few lines I pinched from the include to use glcd_window may be useful to add to the other graphic routines. Surprised you didn't add it as you wrote the glcd include and are familiar with it. A fill routine would be useful now we have pixel read to implement it. Try drawing a dart board without fill. I thought about that and it and remembered doing Bullseye on amstrad converted from bbc micro with no fill. I cheated and made 1/4 of the dartboard a sprite and copied the data to the other 3/4.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
can you adapt the one I just posted? else, I am doing the same thing over and over again which is trying to improve your code and you are not levering.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For a routine I'd suggest sprite (x,y,width,height,ptr)
erase_sprite (x,y,width,height)
The table could be 8 x8, 16 x 16, any size blocks in one table...as is and the ptr to which block to use you choose and set width and height to display that block.
The whole post comes down to this, a sprite sub. It was posted as a guide idea.
Is this what you'd like? As I decribed it's adaptable and seems easy to. I could change the demo to use this and as always, any suggestions welcome.
I would keep draw and erase separate as you might not want to erase just draw.
sub sprite (sprite_x,sprite_y,sprite_width,sprite_height,spritedata_ptr)
SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x +sprite_width-1,sprite_y +sprite_height-1 )
for ptr=spritedata_ptr to spritedata_ptr+(sprite_width * sprite_height)
ReadTable spritedata,ptr,pixel
SendWord_ILI9341 pixel
next ptr
end sub
;
sub erase_sprite (sprite_x,sprite_y,sprite_width,sprite_height) ;write a box of 0's
SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x +sprite_width-1,sprite_y +sprite_height-1 )
repeat 256
SendWord_ILI9341 GLCDBackground
end repeat
end sub
draft idea not tested yet
ps thinking the demo is too big, just as in help, keep it simple, so a simple draw GCB Cow image and data for cow image say 32 x48...and to show off, make it moov :)
Last edit: stan cartwright 2017-11-16
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
you have my code Anobium, I thought it would stay in the forum here to use as wanted.
If you can use it officially then the above sprite and erase sprite with height width, not set as in demo, would be more general purpose.
It wasn't intended for demos, just A demo.
By tomorrow I'll do a proper demo with lot's of explanation griff. I'll send it to @Bed..he won't understand it either :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Stan I must have overseen this.
Did you already sent the demo to me?
Maybe sometimes is something wrong with the sf.net email address so I'll send you my main emailaddress as PM
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is the simplest way to draw a multi coloured sprite I've found. It writes sprite height x width number of words to the display in a graphic window.
Problem is sprite data is stored in tables that can only be 256 items and that includes the 1st byte which holds the table size..from help.
A 16 x 16 pixel sprite is 256 words so as the last pixel is black a problem doesn't show. A square would show the problem but coloured thing looks more interesting.
To get over this table size problem I used two tables and as the sprite sub is only a few lines I copied it to use two tables....I know, sloppy but can't think of another solution other than copy table to array then use that..
It's quite fast visually but could be faster.
https://www.youtube.com/watch?v=Wz8iw07ncqI&feature=youtu.be
Sorry,can't see add file so-
Good stuff
I am not aware of a table limitation of 256. This is an error in the Help - where does it state this. I will revise.
I have just tried the code.
Can you check the code is complete and it works on cleanish installation? I get nothing on the screen. I have used the standard 'GLCD_Read_Demonstation_mega328p_for_ILI9341@16.gcb' as a compplete test and this works ok.
I just downloaded/installed gcb 98.01 again and loaded/flashed program and works ok.
Instead of copy/paste I've attatched the code.
From readtable help-
Item is 1 for the first line of the table, 2 for the second, and so on. Item 0 gives the size of the table. Care must be taken to ensure that the program is not told to read beyond the end of the table, or strange effects will be observed.
I tried using var sprite_ptr. Set to 1 read first sprite table. Set to 257 read second sprite table but didn't!
I can only read 256 of 512 items...words.Note I defined background pixels in table as black not 0 which is one byte as in my previous sprite code and two 12 x 12 sprites was 288 items was not a problem.
Please test readtable for table size.
I will update the Help. There is no limitation on 256 elements. Where exactly is this stated in the Help.
You must therefore use a WORD to read the table data. Try again with a WORD.
In the code I posted I used dim ptr,spritedata_ptr,pixel as word to access table which was one big table not two. Setting ptr to 257 didn't read second table.
Please try to read both tables ie remove end table and table sprite_data2 so it's one 512 item table and please let me know. I'll try to do code to illustrate not more than 256 items. Hope it's an error on my part. Could you not just read a 1000 word table and ser print results to test.
Create one line and copy/paste to many,
you give it a go first, post your results.
I take it back.DOH moment.
I changed sprite sub to one sub and spritedata_ptr points to start of table or 257 items further and it works. This was my first effort that failed. Can't see what I've changed. Hmmmm...
and changed frame to animate between 2 sprites
Last edit: stan cartwright 2017-11-15
I can test. Is this complete working solution?
Did you sort the last byte in the sprite table?
And, we need to agree the standard ports for CS and DC. We are not using the same ports... with one of mine being the same as the Arduino library and your CS&DC neither match. If we aggree on a standard then I will change the demos to suit our new standard ports for CD&DC.
Fair,I changed ports for existing hardware.Posted more in the spirit, I thought it so simple so share.
I added a frame counter to "show" animation at end of demo. Only 2 frames but could be 3 or more.
I've attatched working code that uses "#include <UNO_mega328p.h>" and "DIGITAL_8" for gcb standard for arduino. Should plug play hope
video of code working https://youtu.be/YS2wjLmu4zA
bollards. I can see why you test stuff. For 256 items then I was one out.
Was spritedata_ptr+256. should be
gcb starts at 1
first "item" in table is length of tabel. What is the item , byte,word or long as the items in a table can be byte,word or long?
Confused. Is this a change that needs be made to all the demos?
for ptr=spritedata_ptr to spritedata_ptr+255
Do I need to add?
I have remove
Item 0 gives the size of the table.
from the Help as this is not general rule and is clearly confusing.And, to clarify. Great Cow BASIC table data starts at element 1. The Table handler will look after element Zero for you - so, as a general principle do not ever assume element Zero is the length.
You should use the following principe to ensure that you get it right all the time.
1. The first "item" in table is NOT the length of table.
2. A single value should be on each line
3. Byte, word, longs and integer values are valid (no strings or decimals!)
4. Multiple elements on a single line separated by commas but see item #2 above. A good practice is #2
5. Constants and calculations within the single line data table entries are permitted
6. You can use an external data source file as your table dataset.
7. To read a table of more than 256 elements you MUST you a WORD variable to address the element.
I re-attatched the last code posted, seems ok but I need a magnifier to see the sprite pixels.
It uses
as in the glcd solutions if this is the standard gcb pins for uno.
As you hinted, using glcd window and writing words is faster than checking lit pixels and writing one word at a time. Also the erase is easy to.
Did the code run for you?
ps will miso be defined for read pixel routine?
Works dandy.
The others dont know what they are missing!
I have adapted. Tiny improvements in passing paramers, background color change is now very easy, changing the framerate is now a constant (I like #define bg = teal), I have reverted to UNO Shield naming convension - all the other demos use this method.
If you want to review, and final tweaks, I would gladly publish as a demo.
I want to see the next part of the game when the touch one eats the another! One less.....
I'm implementing collision detection tests. I thought the few lines I pinched from the include to use glcd_window may be useful to add to the other graphic routines. Surprised you didn't add it as you wrote the glcd include and are familiar with it. A fill routine would be useful now we have pixel read to implement it. Try drawing a dart board without fill. I thought about that and it and remembered doing Bullseye on amstrad converted from bbc micro with no fill. I cheated and made 1/4 of the dartboard a sprite and copied the data to the other 3/4.
can you adapt the one I just posted? else, I am doing the same thing over and over again which is trying to improve your code and you are not levering.
For a routine I'd suggest sprite (x,y,width,height,ptr)
erase_sprite (x,y,width,height)
The table could be 8 x8, 16 x 16, any size blocks in one table...as is and the ptr to which block to use you choose and set width and height to display that block.
The whole post comes down to this, a sprite sub. It was posted as a guide idea.
Is this what you'd like? As I decribed it's adaptable and seems easy to. I could change the demo to use this and as always, any suggestions welcome.
I would keep draw and erase separate as you might not want to erase just draw.
draft idea not tested yet
ps thinking the demo is too big, just as in help, keep it simple, so a simple draw GCB Cow image and data for cow image say 32 x48...and to show off, make it moov :)
Last edit: stan cartwright 2017-11-16
So, are you going to do what? I am confused. Are you asking me to change the file I have here?
you have my code Anobium, I thought it would stay in the forum here to use as wanted.
If you can use it officially then the above sprite and erase sprite with height width, not set as in demo, would be more general purpose.
It wasn't intended for demos, just A demo.
By tomorrow I'll do a proper demo with lot's of explanation griff. I'll send it to @Bed..he won't understand it either :)
Hi Stan I must have overseen this.
Did you already sent the demo to me?
Maybe sometimes is something wrong with the sf.net email address so I'll send you my main emailaddress as PM