Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 12:10 17 May 2024 Privacy Policy
Jump to

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 : picoflap

     Page 3 of 4    
Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8603
Posted: 07:07pm 24 Jan 2024
Copy link to clipboard 
Print this post

  Quote  So presumably the sweet spot for smoothness/time would be a step of 2. ;-)


Yep
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3027
Posted: 07:14pm 24 Jan 2024
Copy link to clipboard 
Print this post

Amazing that this kind of speed enhancement can be wrung out at the pretty mature stage of development that the PicoMite is (was) in.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8603
Posted: 07:20pm 24 Jan 2024
Copy link to clipboard 
Print this post

  Quote  Amazing that this kind of speed enhancement can be wrung out at the pretty mature stage of development that the PicoMite is (was) in.


Like everything, its just a case of optimising around the data structures by making more special cases. In this case the framebuffer is nibble based which is clunky to work with.

code before which is still needed for the blitting the physical screen

       if(x1 >= x2) {
           max_x = 1;
           buff = GetMemory(max_x * h * 3);
           while(w > max_x){
               ReadBuffer(x1, y1, x1 + max_x - 1, y1 + h - 1, buff);
               DrawBuffer(x2, y2, x2 + max_x - 1, y2 + h - 1, buff);
               x1 += max_x;
               x2 += max_x;
               w -= max_x;
           }
           ReadBuffer(x1, y1, x1 + w - 1, y1 + h - 1, buff);
           DrawBuffer(x2, y2, x2 + w - 1, y2 + h - 1, buff);
           FreeMemory(buff);
           return;
       }
       if(x1 < x2) {
           int start_x1, start_x2;
           max_x = 1;
           buff = GetMemory(max_x * h * 3);
           start_x1 = x1 + w - max_x;
           start_x2 = x2 + w - max_x;
           while(w > max_x){
               ReadBuffer(start_x1, y1, start_x1 + max_x - 1, y1 + h - 1, buff);
               DrawBuffer(start_x2, y2, start_x2 + max_x - 1, y2 + h - 1, buff);
               w -= max_x;
               start_x1 -= max_x;
               start_x2 -= max_x;
           }
           ReadBuffer(x1, y1, x1 + w - 1, y1 + h - 1, buff);
           DrawBuffer(x2, y2, x2 + w - 1, y2 + h - 1, buff);
           FreeMemory(buff);
           if(Option.Refresh)Display_Refresh();
           return;
           }


Code now which is a special case for framebuffers only

       if((WriteBuf==LayerBuf || WriteBuf==FrameBuf)){
           if((w & 1)==0 && (x1 & 1)==0 && (x2 & 1)==0){ //Easiest case - byte move in the x direction with w even
               if(y1<y2){
                   for(int y=h-1; y>=0;y--){
                       uint8_t *in=WriteBuf + ((y+y1)*HRes + x1)/2;
                       uint8_t *out=WriteBuf + ((y+y2)*HRes + x2)/2;
                       memcpy(out,in,w/2);
                   }
               } else if(y1>y2){
                   for(int y=0;y<h;y++){
                       uint8_t *in=WriteBuf + ((y+y1)*HRes + x1)/2;
                       uint8_t *out=WriteBuf + ((y+y2)*HRes + x2)/2;
                       memcpy(out,in,w/2);
                   }
               } else {
                   for(int y=0;y<h;y++){
                       uint8_t *in=WriteBuf + ((y+y1)*HRes + x1)/2;
                       uint8_t *out=WriteBuf + ((y+y2)*HRes + x2)/2;
                       memmove(out,in,w/2);
                   }
               }
               return;
           } else { //nibble move not as easy
               uint8_t *inbuff=GetTempMemory(HRes/2);
               int intoggle=x1 & 1;
               int outtoggle=x2 & 1;
               int n=w/2;
               if(w & 1)n++;
               if(y1>y2){
                   for(int y=0;y<h;y++){
                       if(!intoggle)memcpy(inbuff,WriteBuf + ((y+y1)*HRes + x1)/2, n);
                       else {
                           int toggle=1;
                           uint8_t *in=WriteBuf + ((y+y1)*HRes + x1)/2;
                           uint8_t *out=inbuff;
                           for(int x=0;x<w;x++){
                               if(toggle){
                                   uint8_t t=*in >>4 ;
                                   *out =t ;
                                   in++;
                               } else {
                                   uint8_t t=(*in & 0xf)<<4;
                                   *out|= t;
                                   out++;
                               }
                               toggle ^=1;
                           }
                       }
                       if(!outtoggle){
                           memcpy(WriteBuf + ((y+y2)*HRes + x2)/2, inbuff, w/2);
                           if(w & 1){
                               uint8_t *lastnibble=WriteBuf + ((y+y2) * HRes + x2 + w)/2;
                               *lastnibble  &= 0xf0;
                               *lastnibble |= (inbuff[w/2] & 0xf);
                           }
                       } else {
                           int toggle=1;
                           uint8_t *in=inbuff;
                           uint8_t *out=WriteBuf + ((y+y2) * HRes + x2)/2;
                           for(int x=0;x<w;x++){
                               if(toggle){
                                   uint8_t t=(*in & 0xf)<<4;
                                   *out &=0x0f; //clear the top byte of the output
                                   *out |=t;
                                   out++;
                               } else {
                                   uint8_t t=(*in >>4);
                                   *out &=0xf0;
                                   *out|= t;
                                   in++;
                               }
                               toggle ^=1;
                           }
                       }
                   }
               } else {
                   for(int y=h-1;y>=0;y--){
                       if(!intoggle)memcpy(inbuff,WriteBuf + ((y+y1)*HRes + x1)/2, n);
                       else {
                           int toggle=1;
                           uint8_t *in=WriteBuf + ((y+y1)*HRes + x1)/2;
                           uint8_t *out=inbuff;
                           for(int x=0;x<w;x++){
                               if(toggle){
                                   uint8_t t=*in >>4 ;
                                   *out =t ;
                                   in++;
                               } else {
                                   uint8_t t=(*in & 0xf)<<4;
                                   *out|= t;
                                   out++;
                               }
                               toggle ^=1;
                           }
                       }
                       if(!outtoggle){
                           memcpy(WriteBuf + ((y+y2)*HRes + x2)/2, inbuff, w/2);
                           if(w & 1){
                               uint8_t *lastnibble=WriteBuf + ((y+y2) * HRes + x2 + w)/2;
                               *lastnibble  &= 0xf0;
                               *lastnibble |= (inbuff[w/2] & 0xf);
                           }
                       } else {
                           int toggle=1;
                           uint8_t *in=inbuff;
                           uint8_t *out=WriteBuf + ((y+y2) * HRes + x2)/2;
                           for(int x=0;x<w;x++){
                               if(toggle){
                                   uint8_t t=(*in & 0xf)<<4;
                                   *out &=0x0f; //clear the top byte of the output
                                   *out |=t;
                                   out++;
                               } else {
                                   uint8_t t=(*in >>4);
                                   *out &=0xf0;
                                   *out|= t;
                                   in++;
                               }
                               toggle ^=1;
                           }
                       }
                   }
               }
               return;
           }
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3585
Posted: 09:18am 25 Jan 2024
Copy link to clipboard 
Print this post

Hi Peter,

I can comfirm that the VGA version is also faster with the new blit implementation.
This will also have impact for the PETSCII game, since it uses the same mechanisms.

Volhout.
Edited 2024-01-25 19:18 by Volhout
PicomiteVGA PETSCII ROBOTS
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3585
Posted: 09:24am 25 Jan 2024
Copy link to clipboard 
Print this post

  thwill said  
   - Have any button except START/SELECT act as "flap"


Yes, will do

  thwill said  
   - Don't auto-repeat when a button is held down, always require that the button state goes from high to low. It looks like you could use the INTL flag with SETPIN and have the interrupt routine set a global flap% variable which is then cleared when you actually "flap".


I will look into this, but using autorepeat is also a way of playing the game (being it more difficult, because one repeat to many and you die).

  thwill said  
   - Consider putting the sprite data as CSUBs in the .bas file instead of a separate ".bin" file. FLASH DISK LOAD is great and was necessary for PETSCII Robots) but you probably shouldn't use it unnecessarily because it increases flash wear.


Honestly Tom, I share your concern, especially since I "RUN" the game every repeat, and every repeat it re-writes flash slot 3. BUT... There is also the PLAY MODFILE, that writes the file into flash. And there is no way around that one. When you stop the sound, and restart, you write to flash again.
So .... unless I find a way to solve the modfile saving, this change does not bring much. Maybe we can detect that the flash slot is containing the correct data, and skip the "overwrite" (FLASH LIST returns "CSub SPRITES" for slot 3).

Volhout
Edited 2024-01-25 19:30 by Volhout
PicomiteVGA PETSCII ROBOTS
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8603
Posted: 09:32am 25 Jan 2024
Copy link to clipboard 
Print this post

  Quote  I can comfirm that the VGA version is also faster with the new blit implementation.
This will also have impact for the PETSCII game, since it uses the same mechanisms.


 
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3863
Posted: 06:55pm 25 Jan 2024
Copy link to clipboard 
Print this post

  Volhout said  BUT... There is also the PLAY MODFILE, that writes the file into flash. And there is no way around that one. When you stop the sound, and restart, you write to flash again.


Peter (if you're reading), if/when there is another firmware update for the PicoMite is there any possibility of functionality to replay the current MODFILE without re-writing it into the flash ?

Also congratulations on the performance improvements to BLIT ... I haven't had the opportunity to play but has this improved the bottleneck of transferring data from the RAM buffers to the LCD display ... presumably this is still limited by the SPI ? I have seen people talking about doing DMA to the ILI9341 for improved performance, but being lazy/busy/stupid (delete as appropriate) not made any great effort to understand, any thoughts ?

Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 414
Posted: 08:06pm 25 Jan 2024
Copy link to clipboard 
Print this post

  Quote  Honestly Tom, I share your concern, especially since I "RUN" the game every repeat, and every repeat it re-writes flash slot 3. BUT... There is also the PLAY MODFILE, that writes the file into flash. And there is no way around that one. When you stop the sound, and restart, you write to flash again.
So .... unless I find a way to solve the modfile saving, this change does not bring much. Maybe we can detect that the flash slot is containing the correct data, and skip the "overwrite" (FLASH LIST returns "CSub SPRITES" for slot 3).

Volhout


Personally I'm not too worried about the Flash wear, the spec. says something around 100K cycles, which at a rate of 50 per day is over 5years, plus a whole Pico only cost £4 to replace! No one seems to think anything of filling up their car, £70 up in smoke, but £4 every 5years is a problem? Anyway in 5years there will be a new improved Pico, perfect timing. :-)
Just my £4 worth. ;-)
Regards Kevin.
Edited 2024-01-26 06:07 by Bleep
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8603
Posted: 10:49pm 25 Jan 2024
Copy link to clipboard 
Print this post

  Quote  Peter (if you're reading), if/when there is another firmware update for the PicoMite is there any possibility of functionality to replay the current MODFILE without re-writing it into the flash ?


Already there

  Quote  BLIT ... I haven't had the opportunity to play but has this improved the bottleneck of transferring data from the RAM buffers to the LCD display ... presumably this is still limited by the SPI ? I have seen people talking about doing DMA to the ILI9341 for improved performance,


No advantage over using cpu2  and the same asynchronous drawbacks
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3863
Posted: 11:33am 26 Jan 2024
Copy link to clipboard 
Print this post

  matherp said  
  Quote  Peter (if you're reading), if/when there is another firmware update for the PicoMite is there any possibility of functionality to replay the current MODFILE without re-writing it into the flash ?


Already there


Thanks Peter, having checked I see that PLAY MODFILE checks the current contents of the buffer against the file before (re)loading it. So that's not a problem @Volhout.

  matherp said  
  Quote  BLIT ... I haven't had the opportunity to play but has this improved the bottleneck of transferring data from the RAM buffers to the LCD display ... presumably this is still limited by the SPI ? I have seen people talking about doing DMA to the ILI9341 for improved performance,


No advantage over using cpu2  and the same asynchronous drawbacks


Thank you Peter.

  Bleep said  Personally I'm not too worried about the Flash wear, the spec. says something around 100K cycles, which at a rate of 50 per day is over 5years.


Good point Kevin.

Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 414
Posted: 08:31pm 28 Jan 2024
Copy link to clipboard 
Print this post

Hi Harm,
I attach a version of Flappy with a step size of 2, both VGA and LCD, which looks nice and smooth to me, but gives the option of speeding up the scroll rate to double what it currently is, if you want.
I have played around with the bird rise and fall speeds, so please set them to whatever you think is appropriate.
Hope this is of use.
Regards, Kevin.

flappy11.zip
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3585
Posted: 08:36am 29 Jan 2024
Copy link to clipboard 
Print this post

Thanks Kevin,

I will look at these. Bus most likely I will only use the LCD version.
The VGA version is plenty fast enough. My plan is to keep developing on VGA.
Since it has all graphical elements as individual sprites, and I can easily modify it, and add to it.

The LCD version requires the "gfx.bin" that is manually created, and thus is less flexible.

VGA = derivatives from "flappy10", will always be leading.
     |
     V
   tools (spr2csub_x (matherp))
     |
     V
LCD version based on "flappy11" derivatives.

I will make a small writeup how to get from VGA to LCD, because I can imagine there are some on the forum that like to use SPRED102(Martin_H) and SSE(VegiPete) to create flying dragons passing over ICE walls/Kings Landing (GOT version) or NazGull flying through MirkWood (LOTR version), all with associated backgrounds.

Regards,

Volhout
Edited 2024-01-29 18:42 by Volhout
PicomiteVGA PETSCII ROBOTS
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 414
Posted: 10:13am 29 Jan 2024
Copy link to clipboard 
Print this post

Ooh that sounds quite advanced for the poor old Picomite. :-)
It's probably quaking in its boots, wondering what we'll be throwing at it next!
I've already got one being tortured by having to control mains voltage on one side and Batteries capable of dumping 2kW very fast on the other. I'm sure we'll be able to stress it some more, GOT style ;-)
I'm quit surprised the Raspberry Pi people haven't taken any interest in the PicoMIte project at all, as far as I can tell?
Regards Kevin.
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3585
Posted: 12:56pm 29 Jan 2024
Copy link to clipboard 
Print this post

Hi Kevin,

It is Raspberry PY. They are promoting Python from the start, and already had to give in to a large amount because Arduino take their board (the pico) as candidate.
Another platform (MMBasic) would (for them) be even more diversification.

And they would get questions from the field. I guess Peter is happy they did not include MMBasic into their portfolio... He is already tired from our (mine, yours, the forum) nagging...

Volhout
Edited 2024-01-29 22:59 by Volhout
PicomiteVGA PETSCII ROBOTS
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 414
Posted: 02:39pm 29 Jan 2024
Copy link to clipboard 
Print this post

I hope Peter enjoys the challenge? If I was as good as he is, I would, but there does come a point where you have to say, for now its got enough features. Maybe what we need is a updated version of the Pico to come along, not likely in the near future, that a new version of MMBasic would be needed for ;-)
I absolutly agree about it being a Raspberry PY Pico, I can sort of understand why, but when you look at how quickly and easily you can throw together a MMBasic program, with peripherals, and, with your inputs, fully & simply, control the PIO... well I like it, and I've spent most of my working life writing 'C'.
Regards Kevin.
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3027
Posted: 02:56pm 29 Jan 2024
Copy link to clipboard 
Print this post

  Bleep said  I've already got one [PicoMite] being tortured by having to control mains voltage on one side and Batteries capable of dumping 2kW very fast on the other


I'd be very interested in seeing what you have done with that project. My mains voltage control has been with Sonoff devices flashed with Tazmota--for monitoring of current of boiler, water pump, freezer, and 2 heat pumps (specifically the Sonoff POW Origin 16A & 20A with ESP32 as controller). I haven't yet introduced the battery backup--that's planned for this summer. Last summer we had 3 10-hour outages.

At this point, the Sonoff devices report changes in current with MQTT (to a Pi MQTT server), but are themselves controlled only separately via browser pages. I plan an integrated controller, but am not yet sure of the platform.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 414
Posted: 03:41pm 29 Jan 2024
Copy link to clipboard 
Print this post

It's been running as was originally shown since last June, I think. The total collected energy was about 39.8KWh, the total used energy, driving fridges and charging everything that is rechargeable, about 36.3KWh as of 1st Jan. Apart from a few minor code updates, like waiting until at least 30W has been put into the batteries before enabling the fridges, (as well as the batteries being sufficiently charged and there is still at least 1.5A coming from the panels), so tweaking with experience gained.
It will still run the fridges in winter, if we get a sunny day, but probably only for an hour or two, which will now slowly be getting greater with any luck. I only started the project because I hated to think that all that solar power was going to waste in the summer, having said that 39.8Kwh is about £14, so I definitely won't ever be in profit, even though almost everthing I used was free/second hand/recycled. ;-)
Regards, Kevin.
PS. It is now in a 'nice' upcycled plastic box. :-)
Edited 2024-01-30 01:47 by Bleep
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3027
Posted: 07:40pm 29 Jan 2024
Copy link to clipboard 
Print this post

  Bleep said  running as was originally shown since last June


Ah, thanks: https://www.thebackshed.com/forum/ViewTopic.php?TID=16055&PID=206580#206580. I see I even commented on it back then.

  Quote  having said that 39.8Kwh is about £14


Wow. In Florida, 39.8kWhr is about $4.78USD at $.12 per kWhr. Same in Canada at $.16CDN, with an exchange rate of about $1CDN to $.75USD. I can see why solar might be attractive in GB even if solar irradiance is low.

(Apologies for going OT on picoflap.)
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3585
Posted: 08:51pm 30 Jan 2024
Copy link to clipboard 
Print this post

All,

This is the VGA only version that I target for conversion to LCD.

It has minor changes

- random night-day
- progressive difficulty
- bronze,silver,and gold medals are awarded at fixed achievements
- to world cup is awarded only for the highest scoring gold winner

I am envisioning WII controller and NES controller support, but want to focus on the Game*Mite LCD version first.

flappyVGA_b1.zip

Unzip to SD card, and RUN "flappy.bas"

Note: do not use XMODEM to run from A: drive. Sprite files get may not work correct anymore.

Volhout
PicomiteVGA PETSCII ROBOTS
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 01:54am 31 Jan 2024
Copy link to clipboard 
Print this post

If you include the trimfile SUB and run each spr file through it, you can use XMODEM again.
The sub only rewrites files that are not a multiple of 128 bytes and you could run it during initial program loading so performance should not be a problem.

The second time you run a file through the sub, nothing will happen.

 MODE 2
 CLS RGB(RED)
 trimfile "nine.spr"
 trimfile "flap3.spr"
 trimfile "bmedalw.spr"
 
 SPRITE LOAD "nine.spr",1
 SPRITE LOAD "flap3.spr",2
 SPRITE LOAD "bmedalw.spr",3
 SPRITE LOAD "bmedalw.spr",4
 
 SPRITE WRITE 1,50,50,0
 SPRITE WRITE 2,100,50,0
 SPRITE WRITE 3,50,100,0
 SPRITE WRITE 4,100,100,0
 
DO:LOOP
END
 
SUB trimfile f$
 LOCAL INTEGER k, fsize, blocks
 LOCAL packet$, tfile$ = "tempfile.txt"
 fsize = MM.INFO(FILESIZE f$)
 IF fsize MOD 128 = 0 THEN ' might be padded by XMODEM
   blocks = fsize/128
   OPEN tfile$ FOR OUTPUT AS #2
   OPEN f$ FOR INPUT AS #3
   FOR k = 1 TO blocks-1 ' we are only interested in the last block
     packet$ = INPUT$(128,#3)
     PRINT #2, packet$;
   NEXT k
   packet$ = INPUT$(128,#3)
   CLOSE #3
   FOR k = LEN(packet$) TO 1 STEP -1
     IF MID$(packet$,k,1) <> CHR$(0) AND MID$(packet$,k,1) <> CHR$(26) THEN
       EXIT FOR
     ENDIF
   NEXT k
   packet$ = LEFT$(packet$, k)
   IF packet$ <> CHR$(0) AND packet$ <> CHR$(26) THEN 'last packet not all pad
     PRINT #2, packet$;
   ENDIF
   CLOSE #2
   KILL f$
   RENAME tfile$ AS f$
 ENDIF
 
END SUB



Tested on a CMM2

Jim
VK7JH
MMedit   MMBasic Help
 
     Page 3 of 4    
Print this page
© JAQ Software 2024