Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 13:44 20 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 : Interrupts for Scrolling and Sprites?

Author Message
JoOngle
Regular Member

Joined: 25/07/2020
Location: Sweden
Posts: 82
Posted: 02:58am 21 Aug 2020
Copy link to clipboard 
Print this post

In the good olden days when I was coding on Amiga and Commodore 64, the main trick we used to get good smooth scrolling was to use interrupts to get perfectly timed scrolling both with bitplanes, sprites and background scrolling.

Can we do something similar with CMM2 and Interrupts?

What I mean, is there a way to ask sprites to continuously increase or decrease their position and let them run independent of MMBasic code?

Same for Scrolling and blitting?

This would increase the power of CMM2 tremendously.
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 04:00am 21 Aug 2020
Copy link to clipboard 
Print this post

  JoOngle said  In the good olden days when I was coding on Amiga and Commodore 64, the main trick we used to get good smooth scrolling was to use interrupts to get perfectly timed scrolling both with bitplanes, sprites and background scrolling.

Can we do something similar with CMM2 and Interrupts?

There's the interrupt you can set with MODE, which has the right timing for this. (SETTICK being an option if you want different timing)
  Quote  
What I mean, is there a way to ask sprites to continuously increase or decrease their position and let them run independent of MMBasic code?

Same for Scrolling and blitting?

This would increase the power of CMM2 tremendously.


You'd need to put MMBasic code for doing the updates in the SUB called by the interrupt, but the timing could be independent of other MMBasic code.

edit: Also for sprites it's easiest to do all of them at once with SPRITE MOVE (after setting any changed positions with SPRITE NEXT) so you don't need worry about moving sprites underneath other sprites.
Edited 2020-08-21 14:10 by capsikin
 
JoOngle
Regular Member

Joined: 25/07/2020
Location: Sweden
Posts: 82
Posted: 03:03pm 21 Aug 2020
Copy link to clipboard 
Print this post

IMHO. real sprites should simulate hardware sprites like on the Atari/Amiga/Commodore 64.

As they are on the CMM2 (afaik), they are merely memcopy from "memory" to "other place in video memory", and it's not even fixed.

On a commodore 64 for example, when you type text, the sprites will remain on the screen and not become erased by the text, this enables scrolling and the use of these sprite objects (as real sprites) where they don't affect the foreground or background graphics by leaving "garbage" trails behind them, and you don't need to use a framebuffer to "erase" the garbage (which just takes up extra time anyway).

Every sprite should have its own memory allocation, and be entirely independent of the main screen (they should be superimposed on the main video memory, but non-destructively).

As the sprites are now, they are "destructive".

Same for scrolling bitmaps. Like on the Amiga, every bitmap is independent of each layer (except for color combinations, you add a certain amount of bitmap to add to color resolution), but they don't interfere with each other, in other words - they are non destructive hardware screens.

This I believe could be emulated on the CMM2 if hardcoded correctly and interrupts used correctly as well.
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3678
Posted: 04:31pm 21 Aug 2020
Copy link to clipboard 
Print this post

If the hardware simply will not do sprites the way you want, would you rather have sprites as they are or no sprites?

It may be that's the issue...

John
 
MauroXavier
Guru

Joined: 06/03/2016
Location: Brazil
Posts: 303
Posted: 04:55pm 21 Aug 2020
Copy link to clipboard 
Print this post

For most things, I even donīt need sprites. The CMM2 is so fast that you can clear all screen, insert then the background, fill with sliced images copied from other video pages (as sprites or shapes), push all to a framebuffer and finally copy it to the main video page and so on.

If you want sprites with some independent connection with background, you can maintain a fixed 2 layers with 12-bit screen mode, including the use of transparency.
 
berighteous
Senior Member

Joined: 18/07/2020
Location: United States
Posts: 110
Posted: 10:33pm 21 Aug 2020
Copy link to clipboard 
Print this post

It's really easy to layer up everything in the framebuffer and then scroll everything together by moving the area of the frame buffer you blit to page 0 to see.
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 01:41am 22 Aug 2020
Copy link to clipboard 
Print this post

  JoOngle said  IMHO. real sprites should simulate hardware sprites like on the Atari/Amiga/Commodore 64.

As they are on the CMM2 (afaik), they are merely memcopy from "memory" to "other place in video memory", and it's not even fixed.

On a commodore 64 for example, when you type text, the sprites will remain on the screen and not become erased by the text, this enables scrolling and the use of these sprite objects (as real sprites) where they don't affect the foreground or background graphics by leaving "garbage" trails behind them, and you don't need to use a framebuffer to "erase" the garbage (which just takes up extra time anyway).

Every sprite should have its own memory allocation, and be entirely independent of the main screen (they should be superimposed on the main video memory, but non-destructively).

As the sprites are now, they are "destructive".

Same for scrolling bitmaps. Like on the Amiga, every bitmap is independent of each layer (except for color combinations, you add a certain amount of bitmap to add to color resolution), but they don't interfere with each other, in other words - they are non destructive hardware screens.

This I believe could be emulated on the CMM2 if hardcoded correctly and interrupts used correctly as well.


I would be interested to see a library to simulate this.
You could call SPRITELIB.MODE 3,8,0,1,2 and the library would set MODE 3,8, and would include its interrupt routine, and would remember page 0 as the page to combine the sprites and background onto, page 1 as the page for the background, and page 2 as the page for the sprites.

Some of the SPRITE commands would have new library commands starting with SPRITELIB that you call instead.

Then later when you do SPRITELIB.NEXT 3,70,80, it calls SPRITE NEXT 3,70,80 in page 2, and in the interrupt after that, SPRITE MOVE, and PAGE COPY and BLIT to finish the sprite move and combine pages 1 and 2 onto page 0. (Maybe there's a more efficient way, but that should work).

After a SPRITELIB.NEXT command that changes the write page, maybe it changes it back to the background page, so any print or graphics commands you do write to there.

(update: I can't do it this way - due to the full screen BLIT with transparency support, it doesn't complete within a single frame time, at least in mode 1)
Edited 2020-08-22 15:17 by capsikin
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 04:27am 23 Aug 2020
Copy link to clipboard 
Print this post

First quote's from another thread:

  JoOngle said  IMHO sprites should be non-destructive aka not interfere with the background (or any foreground) graphics at all.

Hide and restore is a needed function, but to use it to allow other changes to happen to the screen is sorta cheating and will make games horribly slow when this could all be done in the OS itself. (not a critique, thanks for your amazing work Peter), it's just an observation (not to mention, perhaps wishful thinking here), but then again I come from a background where sprites where real sprites, aka totally independent of the background graphics, like miniature screens if you like. Even the arcade machines had these sprites often referred to as "player / missile" objects.


I think some of it's wishful thinking and either requires different hardware or too much change to the firmware.

SPRITE HIDE ALL / SPRITE RESTORE could be called just once each per frame, and should be quick for small numbers/areas of sprites. For many programs MauroXavier's other suggestions would work better. Both cases could probably also use a PAGE COPY or two. That's only 3 or 4 commands and then the OS/MMBASIC does all the work within those commands itself. I think you're underestimating the amount of work the sprite-supporting graphics chips had to do. They'd check every pixel to see if it should have the sprites overlayed on top. That's the equivalent of doing page copies, or even slower full page blits that check for transparent pixels, if you had to do it in software and memory.

  JoOngle said  IMHO. real sprites should simulate hardware sprites like on the Atari/Amiga/Commodore 64.

As they are on the CMM2 (afaik), they are merely memcopy from "memory" to "other place in video memory", and it's not even fixed.


Not sure what you mean by "not even fixed".

  Quote   On a commodore 64 for example, when you type text, the sprites will remain on the screen and not become erased by the text, this enables scrolling and the use of these sprite objects (as real sprites) where they don't affect the foreground or background graphics by leaving "garbage" trails behind them, and you don't need to use a framebuffer to "erase" the garbage (which just takes up extra time anyway).

Every sprite should have its own memory allocation, and be entirely independent of the main screen (they should be superimposed on the main video memory, but non-destructively).

As the sprites are now, they are "destructive".


Except for simple layering like the 12 bit mode, I doubt the video chip can do the complex operations required, which means the processor has to do them, and store the result in memory for the video chip to read.

So the processor can take a background, not modify the original but make a copy that it puts the sprites on[1], and the video chip displays that. Is that non-destructive like you meant?

This is quite similar to what sprite hardware would do, except it stores the result in memory instead of outputting to the screen in real time.

[1] If you're always drawing sprites on a fresh copy of the background, you don't need the slower sprite show/hide system, you can use BLIT or SPRITE WRITE.

There's some other differences in how it's used currently that are maybe what you want to do differently:

It stores the result using a whole screen of memory instead of maybe just some internal registers for a few pixels or a single line at a time.

Sometimes it may need to use slower DRAM if all the faster RAM is already in use - this is probably something to avoid when you need speed.

Processing the whole screen at a time means there's more latency, so to avoid showing incompletely processed graphics, you use a separate buffer and an extra copy. Which takes extra time.

The program has to have code for copying from the background to the screen memory and putting the sprites on top - this is where a library would be good.

  Quote   Same for scrolling bitmaps. Like on the Amiga, every bitmap is independent of each layer (except for color combinations, you add a certain amount of bitmap to add to color resolution), but they don't interfere with each other, in other words - they are non destructive hardware screens.

This I believe could be emulated on the CMM2 if hardcoded correctly and interrupts used correctly as well.


What kind of emulation are you imagining? I think there are some types that might work, and I'm also interested in more speculative thoughts.
 
JoOngle
Regular Member

Joined: 25/07/2020
Location: Sweden
Posts: 82
Posted: 05:11am 23 Aug 2020
Copy link to clipboard 
Print this post

This entire thread should be merged with your thread Capsikin, because I think we essentially just both want the same thing, I won't be quoting large sections of your text above, but instead I will try to simplify my wishes.

However - I can see that Peter has implemented a LOT of improvements to the sprite function lately which is thrilling to say the least :)

I fully realize that we can't have real hardware sprites as this would have to be a part of the graphics card "function" itself within the processor, but it's possible to to emulate it, I will simplify my explanation as well as I can.

A sprite object, in hardware as it has been done traditionally in retro computers over the years is essentially like a mini-graphics screen with it's own internal video ram, it can access the basic ram shared with the processor.

On the Commodore 64, Atari and Amiga (and even the arcade machines) these sprites where hardware screens that could be moved freely over the main graphics screen without interfering with the background, in other words they weren't objects that were copied from the main video memory (the graphics screen itself), but they where independent fixed size miniature screens where you could display either coloured objects or one color objects depending on what "sprite mode" you set. Colours often demanded more bit combination to create colours at the cost of resolution in these mini hardware screens.

The commodore 64 had 8 sprites, they were addressable in the same way you address graphics video memory the same way you address video memory, except they are really independent screens that would be visible on top of the existing video memory, but they would not be destructive which simply means if you did anything to the main screen (main video memory) they would not be affected, you could draw anything  you want in real time, and the sprites would still be unaffected and untouched and still remain in their intended x,y position. Even if you changed the graphics mode (resolution) for the main video memory, the sprites would not be affected, and if you changed the video mode for the sprites, the background would remain unaffected by this as well.

To overcome the 8 sprite limitation the Commodore 64 had, we used interrupt timing of the processor to "cheat" it, but if you had more than 8 sprites next to each other, this would affect the timing, so you would have the flickering effect you can see on the Atari 2600 Asteroids, where the asteroids themselves is flickering because they are changing between visible and non-visible (like turning them on and off, with the timing of the video update (50 or 60 FPS depending on what video system you were using back in those days) 50 or 60 Hz if you like. Pal and NTSC.

All emulators created to date, whether this is an Atari Emulator, Commodore 64 Emulator etc, uses software simulation of course, since the PC doesn't have this hardware feature, you could argue that you could use 3D graphics functions like the Nvidia and AMD graphics card have to use them as sprites instead as the polygons essentially also functions like "miniature graphics screens" with textures that can be moved around independently of the main graphics video memory.

If you don't want to read all the above, here's my simplified suggestion on how to implement this on CMM2:

1) Create a fixed number of sprites to emulate, 64 sprites is a BIG ask, 16 would be just fine even though more is desireable, but we do have speed limitations after all on a 400/480 MHz risc processor.

2) The sprite would function like this.

- It has it's own fixed video memory (non visible on the main video memory), you can refer to a part of the memory where it will get it's data, call it sprite-memory if you like,

- It will update with the speed of the screen refresh, so if the screen refresh is 60 Hz, this is how often the sprite will be re-drawn. Now - since we do not HAVE a hardware function like this, refreshing the sprites 60 times per second would be costly if the sprite or the background isn't moving, because it would use up processor power for no apparent reason at all, so I suggest that the sprite refresh happens only if there is any screen activity on the sprite itself or background (main video memory).

- What the sprite will do, is to function like its own independent mini screen that "floats" on top of the main video screen. Since we don't have real hardware to do this, we can use the timing of the screen refresh to update it.

- The sprite is displayed like, if we move it from x1,y1 to position x2,y2 it will non destructively move it from position x2,y2, but it will leave the video memory of the main screen intact, meaning whatever was BEHIND the sprite (in the main graphics screens video memory) will be copied right back where it was. Now if you make this like it is NOW with the new functions in CMM2, you will have to explain this to the sprite in basic by clearing the sprites, updating the video memory with a new copied image (which is very costly, but in assembly code (or compiled C if you like) was done entirely in assembly/c compiled code - you wouldn't have to do this in basic, and this would make the basic way more powerful since you leave the basic for the software (game) itself, rather than having to do the job of the sprite copy/pageflip/or whatever.

The sprite itself should work entirely independent of whatever you do with the main video memory, the main video memory has to be entirely intact regardless of how you move the sprites around, when a sprite is placed onto the screen, ofc it erases whatever graphics was behind it in the main graphics video memory, but the EMULATION should COPY the information that WAS BEHIND the sprite - BEFORE it was placed, and if you decide to MOVE the sprite, the information that WAS BEHIND the sprite's position should be immediately REPLACED with each screen refresh (if there are any changes in movement either in video memory or in sprite video memory).

In order to avoid timing issues /judder / FPS skips) this should NOT be done with commands in basic such as hide/show etc, as it will eventually result in frame-skips that are visible. And it should leave the main video memory entirely unaffected by the sprites movements or placements, leave no "trails" so to speak.

I don't know if it can be done, I realize the Flash memory is limited, and Peter can do only so much with it, but I hope the above explains proper sprite functions clearly.

If not, then I apologize for my sucky explanation. Also I realize this is entirely voluntary work,so these suggestions is by no means demands or critique, it is just suggestions, that's all.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 09:14am 23 Aug 2020
Copy link to clipboard 
Print this post

JoOngle

Have you got a CMM2 up and running yet?

Much of what you want is already there and there are multiple ways of doing things. Sprites do save the background and replace it when moved. This has always been the case. The new functionality deals with sprites overlapping other sprites.

Capsikin has been working with the sprite code and made suggestions based on his experience of some limitations which I was pleased to try and address. Most developers are using BLIT rather than sprites which, because you have multiple video pages, allows you to do pretty much everything that a sprite can do. The key advantage of sprites is the in-built collision detection.

I'm not going to make any changes to the overall architecture as this could kill existing programs. I will potentially add functionality if I can be persuaded there is a practical case for it rather than a theoretical one.
 
JoOngle
Regular Member

Joined: 25/07/2020
Location: Sweden
Posts: 82
Posted: 09:26am 23 Aug 2020
Copy link to clipboard 
Print this post

Yes Peter, and I've been testing everyone's code examples, and they do have the limitation of timing, judder, and if we dont use sprite hide - it will draw a long line of "smear" behind it, but the sprite will move smoothly instead, now the sprite hide should be automatic, not needed in MMBasic as "sprite hide" just to do that function, that function should be done by default.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 09:37am 23 Aug 2020
Copy link to clipboard 
Print this post

  Quote   it will draw a long line of "smear" behind it,


I don't understand what you mean. SPRITE SHOW moves the sprite without leaving anything behind. Some of the examples are not coded correctly. Try the attached.


tennis.zip
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 04:46pm 23 Aug 2020
Copy link to clipboard 
Print this post

  JoOngle said  The sprite itself should work entirely independent of whatever you do with the main video memory, the main video memory has to be entirely intact regardless of how you move the sprites around, when a sprite is placed onto the screen, ofc it erases whatever graphics was behind it in the main graphics video memory, but the EMULATION should COPY the information that WAS BEHIND the sprite - BEFORE it was placed, and if you decide to MOVE the sprite, the information that WAS BEHIND the sprite's position should be immediately REPLACED with each screen refresh (if there are any changes in movement either in video memory or in sprite video memory).

This is tricky to do if there might be overlapping sprites.

If you only copy the background, then when you move the sprite away you'll erase all the other sprites at the same location. But if you copy what was already on the screen, then when you move the sprite away it will redraw any sprites that had been underneath it - even if they'd already moved away.

That's why the existing sprite system sometimes needs to erase and redraw all the sprites.

If you don't care about that, this is basically how the sprite system moves sprites when you use SPRITE SHOW (without hide). You'd still need to add an interrupt that calls that at the right time.

But it wouldn't work well with overlapping sprites.

If you want to change the background while a sprite is onscreen, that's also tricky. If you just do drawing command, it overwrites the sprites. If you redraw the sprites, they don't know their correct backgrounds, so when they move away they'll mess up the screen.

  Quote  
In order to avoid timing issues /judder / FPS skips) this should NOT be done with commands in basic such as hide/show etc, as it will eventually result in frame-skips that are visible. And it should leave the main video memory entirely unaffected by the sprites movements or placements, leave no "trails" so to speak.

I don't know if it can be done, I realize the Flash memory is limited, and Peter can do only so much with it, but I hope the above explains proper sprite functions clearly.

If not, then I apologize for my sucky explanation. Also I realize this is entirely voluntary work,so these suggestions is by no means demands or critique, it is just suggestions, that's all.


Here's my idea, doing it all with a BASIC library:
You have one page that's the background. (maybe page 1)
You have one page with the sprites and background combined. (maybe page 2)
And the output page 0, which also has the sprites and basic combined.

You draw whatever you want one the background page.
You set the sprites to move on page 2 with SPRITE NEXT.

There's a frame update SUB which hides the sprites on page 2, copies the background onto the page, then restores the sprites. Maybe you call it, and afterwards it copies the page to the output page.

Alternatively, you have a screen blanking interrupt which copies page 2 to the output page 0, then calls the frame update sub. And it had better set PAGE WRITE back after changing it for the SPRITE HIDE/RESTORE.

If it's fast enough I don't see why it should have frame skips.

The interrupt part could be a bit tricky, but the rest seems quite straightforward.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 04:58pm 23 Aug 2020
Copy link to clipboard 
Print this post

  Quote  Here's my idea, doing it all with a BASIC library:


Don't forget 12-bit mode. Just maintain the sprites on one page and the background on another. Then, whenever required copy the sprite page to page 1 and the background to page 0 and let the hardware do the rest.
 
JoOngle
Regular Member

Joined: 25/07/2020
Location: Sweden
Posts: 82
Posted: 03:59am 24 Aug 2020
Copy link to clipboard 
Print this post

  matherp said  
  Quote  Here's my idea, doing it all with a BASIC library:


Don't forget 12-bit mode. Just maintain the sprites on one page and the background on another. Then, whenever required copy the sprite page to page 1 and the background to page 0 and let the hardware do the rest.


And here we touch the main thing! IMHO the sprites should maintain themselves, automatically do the copying without the need to command that from basic.
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 06:42am 24 Aug 2020
Copy link to clipboard 
Print this post

  matherp said  
  Quote  Here's my idea, doing it all with a BASIC library:


Don't forget 12-bit mode. Just maintain the sprites on one page and the background on another. Then, whenever required copy the sprite page to page 1 and the background to page 0 and let the hardware do the rest.


Yes I forgot 12 bit mode's good for this. I'd been thinking about a system using more than two layers.

One subtlety though, if you just page copy both pages on the screen blanking interrupt, whichever you copy second may not be ready in time as the screen starts displaying.

One idea I kind of like:
The library manages copying the sprite page in screen blanking interrupt, and updating it.
The program can write directly on page 0 for the background, or via another page and copy it to page 0.

Should be very simple and easy to use. I don't think it gives tear-free background updates though.

  JoOngle said  
  matherp said  
  Quote  Here's my idea, doing it all with a BASIC library:


Don't forget 12-bit mode. Just maintain the sprites on one page and the background on another. Then, whenever required copy the sprite page to page 1 and the background to page 0 and let the hardware do the rest.


And here we touch the main thing! IMHO the sprites should maintain themselves, automatically do the copying without the need to command that from basic.


Not even if the basic command is in an interrupt in a BASIC library, so there main program doesn't need to do it?
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 07:14am 24 Aug 2020
Copy link to clipboard 
Print this post

  Quote  And here we touch the main thing! IMHO the sprites should maintain themselves, automatically do the copying without the need to command that from basic.


Yes but they don't and are not going to so it is pointless to keep raising the issue

  Quote  One subtlety though, if you just page copy both pages on the screen blanking interrupt, whichever you copy second may not be ready in time as the screen starts displaying.


The way I would do it is to refresh each page alternately so you get a 37.5Hz effective rate. Use the frameblanking interrupt to trigger the copy and maintain a toggle to know what to copy next with a test to see if a copy is required at all. i.e. has anything changed
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3027
Posted: 09:09pm 28 Aug 2020
Copy link to clipboard 
Print this post

Tennis.zip appears to be missing "cartoon" and "gunshot"--where are they?
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
capsikin
Guru

Joined: 30/06/2020
Location: Australia
Posts: 341
Posted: 05:50am 29 Aug 2020
Copy link to clipboard 
Print this post

  lizby said  Tennis.zip appears to be missing "cartoon" and "gunshot"--where are they?


Oops, I noticed that too but forgot to say something.
Edited 2020-08-29 15:50 by capsikin
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 07:31am 29 Aug 2020
Copy link to clipboard 
Print this post

God you lot want spoon feeding  Any mod file and any wav could be substituted - its just a demo


tennis.zip
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024