Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : MM2: Sprite magic (thanks darthmite)
Author | Message | ||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
See the video Fabrice (darthmite) has written a beautiful program for creating sprites (full colour bitmaps) available here . I have also shamelessly stolen his example sprites to use on the Micromite in my test program. To do this I've written a little MMBasic for DOS program that takes his output file format and converts it into Micromite compatible "DATA" statements: open "sprite.bin" for INput as #1 open "sprite.bas" for output as #2 i=0 nsprites=asc(input$(1,#1)) a=asc(input$(1,#1)) width=asc(input$(1,#1)) a=asc(input$(1,#1)) height=asc(input$(1,#1)) a=asc(input$(1,#1)) print #2,"DATA "+STR$(nsprites)+","+str$(width)+","+str$(height)+" '# sprites, sprite width, sprite height" for i=0 to nsprites print #2,"'Sprite no "+str$(i) for j=0 to 31 for k=0 to 31 if j<height and (k=0 or k=16) then PRINT #2,"DATA "; a=asc(input$(1,#1)) b=asc(input$(1,#1)) if b and &HF8 then : red$=right$(hex$((b and &HF8) + 263),2) : else : red$="00" : endif if a and &H1F then : blue$=right$(hex$(((a AND &H1F) * 8) + 263),2) : else : blue$="00" :endif if (b and &H07) OR (a and &HE0) then : green$=right$(hex$((b and &H07 )*32 + (a and &HE0)/8 + 259),2) : else : green$="00" : endif if red$="00" then red$="" if green$="00" and red$="" then green$="" if green$="" and left$(blue$,1)="0" then blue$=right$(blue$,1) prelim$="" else prelim$="&H" endif if k<width-1 and j<height and k<>15 then print #2,prelim$+red$+green$+blue$+","; if ((k=width-1 or k=15) and j<height) then print #2,prelim$+red$+green$+blue$ next k next j a=asc(input$(4,#1)) next i close #1 close #2 end I've then written a CFunction that allows one or more sprites to be displayed on a SSD1963 screen. Of course a "sprite" need not be a complex graphic but could equally be a text character. The code would then allow text to be superimposed on a pre-defined background rather than overwriting it. There is one callable CFunction SPRITE. This takes the following parameters: Mode: can be clearsprite=0, writesprite=1, movesprite=2 RDpin: The number of the pin connected to the RD input of the display, needed to read the display memory X%: x-coordinate of the top left of the sprite to be written or displayed Y%: y-coordinate of the top left of the sprite to be written or displayed width%: width of the sprite in pixels height%: height of the sprite in pixels displaybuff: an array used to hold the contents of the display memory before displaying the sprite OPTIONAL spritebuff: an array holding the pixel information for the sprite, not needed for the clear mode OPTIONAL NewX: x-coordinate of the top left of the new position of a sprite to be moved, in this case X% holds the original position OPTIONAL NewY: y-coordinate of the top left of the new position of a sprite to be moved, in this case X% holds the original position The way the sprite write-mode processing works is to: Save the existing display contents in the area defined by x,y,width,height Write out the sprite but overwrite only those pixels which are non-zero in the Sprite Move mode works by: Restoring the display content in the area where the sprite was originally located Saving the display contents in the area where the sprite will now be located Write out the sprite but overwrite only those pixels which are non-zero in the Sprite Move mode is the same as doing a "clear" followed by a "write", but because it is done as a single CFunction call it is much quicker. Note in the video there is a 40msec wait between each "step" so the update capability is much faster than shown. At the moment the code will only run on a 44-pin Micromite uM2 using a loadable SSD1963 driver (included in the example code) and it needs the pinout set as below: you must use pins 25,26,27,36,37,38,2,3 for the data pins DB0-DB7 you must use pin 4 for RS and pin 5 for WR Tie CS Low connect RD to an unused Micromite output and set the pin number in MM.STARTUP connect RST to an unused Micromite output and set the pin number in MM.STARTUP I will write a version for the MM+ once I have a suitable test system available. My test code for the example above is: 2015-10-04_105929_spritedemo.zip If you run this you will find reading of the Sprite DATA statements takes a long time (> 1min). At a later date I will replace these with a Data CFunction but for development the DATA/READ structure was more convenient. The Basic code uses one sneaky technique. When you pass an array to a CFunction you are actually passing the address of the first element in the array. Therefore it is also OK to pass a specific element of the array i.e. CFUNC(array()) is the same as CFUNC(array(0)). This also allows us to pass an offset into the array: CFUNC(array(10)) will pass the address of the 10th element. If you look at the example code you will see I store 7 sprites in a 2-dimensional array. I can then pass the address of the start of a specific sprite by using a specific location in the array in the call to the CFunction. The same technique is used to store the pre-existing display data in a two dimensional array where the second dimension refers to the instance of the sprite. The sprite and display information is stored in RGB888 format with two pixels stored in each 64-bit integer (see the READ loop in the code to understand this). Note the number and size of sprites is defined by the amount of flash (sprite definitions) and RAM (Sprite instances) available. Both of these will of course increase on a MM+. The code cannot be modified to run on a ILI9341 SPI display as the way these displays are wired does not support reading the graphics memory. C-code for those interested: 2015-10-04_113446_SPRITE.zip |
||||
darthmite Senior Member Joined: 20/11/2011 Location: FrancePosts: 240 |
And i have 'shamelessly' stole them from Turrican game I given the full Lemmings pack to Uwe too , i don't know what is on the zip in his page. For Lemmings , the original are so small that i go for made a 'Double Size' button on the Sprite Editor. Most of 'old' games with sprite are not often bigger than 16x16 pixels , then this option will be good to do ... Here on stmF7Mite (480 x 272) the Turrican are just the right size , but not Lemmings (i need my google) Cheers. Theory is when we know everything but nothing work ... Practice is when everything work but no one know why ;) |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
Updated code to use the V2 loadable driver developed for the text overlay and other optimisations 2015-10-05_145358_spritedemo.zip |
||||
OA47 Guru Joined: 11/04/2012 Location: AustraliaPosts: 904 |
Peter, can I ask how or where you obtained the enclosure for the screen? GM |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
It is 3D printed. I'm away from home at the moment but can post the .STL file when I get home |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
3D model attached as promised. Note the cutouts for the header pins and the touch screen cable and model file: 2015-10-13_133222_mountforscreen.zip |
||||
OA47 Guru Joined: 11/04/2012 Location: AustraliaPosts: 904 |
Peter, thank you for that info. GM |
||||
Print this page |