Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 14:49 16 Nov 2025 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 : CMM2: Sprite vs. background question

Author Message
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 09:28am 13 Oct 2020
Copy link to clipboard 
Print this post

Hi all,

I don't fully understand how on CMM2 sprites work relative to the background.

I'm in 8-bit mode. I have a sprite the size of a character. Here is the code fragment that confuses me:


TEXT 0,0, "A"   '1. Shows letter A in upper left corner
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP 'Wait for key press
SPRITE SHOW 2, 0, 0, 2  '2. Shows sprite with letter A underneath.
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP 'Wait for key press
TEXT 0,0, "V" '3. Show letter V in upper left corner
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE SHOW 2, 0, 0, 2 '4. Show sprite with letter A underneath (why not V?)


Step 3. The letter V overwrites the sprite. This shows that sprites don't live in a separate plane before or behind the background. They behave more like stickers that get pasted on the background. OK.

Step 4 however I don't understand. I'm redisplaying the sprite here so I was expecting to see the sprite with the letter V underneath. Instead I see the letter A underneath. Where did that come from?

Here is the full code:


OPTION BASE 0
MODE 1, 8
FONT 1, 1

DIM CRSR_INS_SPRITE%(MM.INFO(FONTWIDTH)*MM.INFO(FONTHEIGHT)-1)
CRSR_INS_SPRITE_DATA:
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0
DATA RGB(WHITE), RGB(WHITE), 0, 0, 0, 0 ,0 ,0

SUB initInsSprite
 LOCAL ii%

 RESTORE CRSR_INS_SPRITE_DATA
 FOR ii%=0 TO MM.INFO(FONTWIDTH)*MM.INFO(FONTHEIGHT)-1
     READ CRSR_INS_SPRITE%(ii%)
 NEXT ii%
END SUB

initInsSprite

SPRITE LOADARRAY 2, MM.INFO(FONTWIDTH), MM.INFO(FONTHEIGHT), CRSR_INS_SPRITE%()

TEXT 0,0, "A"
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE SHOW 2, 0, 0, 2
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
TEXT 0,0, "V"
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE SHOW 2, 0, 0, 2



Thanks for any help,
Ruben/Epsilon
Epsilon CMM2 projects
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10588
Posted: 09:45am 13 Oct 2020
Copy link to clipboard 
Print this post

Sprites are implemented in S/W. When you first display a sprite it saves the background where it will be displayed and then overwrites it. When you move a sprite it restores the stored background in the old position, stores the background in the new position and then writes out the sprite.

If you need to write to the screen with non-sprite commands you must hide any sprites that may be overwritten first and then restore them after the non-sprite write.

An alternative is to write the sprites to a cleared to black page and then blit that page with transparency to the page on which you are using non-sprite writes.

Another alternative is to use 12-bit mode. Have the sprites on page 1 and everything else on page 0
Edited 2020-10-13 19:47 by matherp
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 10:20am 13 Oct 2020
Copy link to clipboard 
Print this post

Thank you for the quick response!

So this works fine:


TEXT 0,0, "A"
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE SHOW 2, 0, 0, 2
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE HIDE 2 'Hide sprite because it will be overwritten.
TEXT 0,0, "V"
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE SHOW 2, 0, 0, 2 'Redisplay sprite


  matherp said  
An alternative is to write the sprites to a cleared to black page and then blit that page with transparency to the page on which you are using non-sprite writes.


Got it. So sprites don't automatically live on a separate 'plane', but you can still make it so. Cool!
Epsilon CMM2 projects
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 07:59am 18 Nov 2020
Copy link to clipboard 
Print this post

I ran into a subtle issue with BLIT which manifests itself as an 'incorrect sprite background' issue, which started this thread.

Here is a code snippet that triggers the issue:


SPRITE LOADARRAY 2, 8, 12, CRSR_INS_SPRITE%()
DIM s0$ = "'--> Key Codes. Press Alt-K in the editor to see the keycode corresponding to a keypress. Combos with Ctrl, Shift and Alt are supported.  "
DIM s1$ = "'CONST FG_COLOR% = RGB(230, 230, 230)"

PAGE WRITE 4
CLS
TEXT 8, 12, MID$(s0$, 1, 98)
PAGE WRITE 0
CLS
TEXT 8, 12, MID$(s0$, 1, 98)
SPRITE SHOW 2, 98*8, 12, 1, 0
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE HIDE 2
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
TEXT 8, 12, MID$(s0$, 40, 98)
BLIT 8, 24, 8, 24, 0, 12, 4
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP
SPRITE SHOW 2, 98*8, 12, 1, 0


So, in a nutshell:
1. I print a line of text and overlay a cursor shaped sprite.
2. I hide the sprite.
3. I modify the line of text.
4. I do a blit to a different part of the screen.
5. I redisplay the cursor shaped sprite.

The redisplayed sprite in step 5 now has an incorrect background. It looks as if I forgot to hide the sprite in step 2.

The issue is triggered by the funny BLIT in step 4. This BLIT has a width of 0.

You might just say "don't do that" and move on. My workaround is of course to protect the BLIT with an 'if width > 0...' (in my actual code, the BLIT parameters are the result of a computation obviously). However, I have two issues with this:

1. I now have to 'special case' an otherwise linear sequence of code. But more importantly:
2. BLIT doesn't flag a width of 0 as invalid. The BLIT proceeds as expected. It's only later, in a different part of the graphics subsystem (sprites) that an issue appears, which makes it very hard to track down the problem.

I have attached the complete test program.

Cheers,
Ruben/Epsilon.

xdbg.zip
Epsilon CMM2 projects
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10588
Posted: 10:51am 18 Nov 2020
Copy link to clipboard 
Print this post

What version? - the code suggests this is fixed in RC21
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 11:40am 18 Nov 2020
Copy link to clipboard 
Print this post

This is still 5.05.05.

I haven't been brave enough to jump on the early adapter beta FW bandwagon.
The problem is that the program I'm writing and debugging is itself in alpha/beta stage and I'm just not looking forward to testing and debugging my alpha SW on beta FW.

Great to hear that this issue will be fixed in the next FW release however!
Epsilon CMM2 projects
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 290
Posted: 02:45pm 18 Nov 2020
Copy link to clipboard 
Print this post

Ruben,

Just curious - why the DO:INKEY:LOOP twice? Shouldn’t once be enough?

FYI, I went the other way i.e. towards the bleeding edge. Now, I think the springy things on my programming jumper block are wearing out from the daily firmware updates!

BTW, I distinctly remember (and it’s here on TBS somewhere...) Peter saying the CMM2 FW was feature complete, and no updates other than for bug fixes ;)

Cheers, and keep up the great work!
Enjoy Every Sandwich / Joe P.
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1680
Posted: 02:58pm 18 Nov 2020
Copy link to clipboard 
Print this post

  RetroJoe said  ...Just curious - why the DO:INKEY:LOOP twice? Shouldn’t once be enough?

It is not the same twice!
DO WHILE INKEY$="":LOOP:DO WHILE INKEY$<>"":LOOP

The first loop stops as long as no key is pressed.
The second loop stops while a key is pressed.

Regards
Michael
Edited 2020-11-19 01:16 by twofingers
causality ≠ correlation ≠ coincidence
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 533
Posted: 05:26pm 18 Nov 2020
Copy link to clipboard 
Print this post

I'm using it same way to prohibit "stuck" keys (but anyways it sometimes doesn't help...).
Jiri
Napoleon Commander and SimplEd for CMM2 (GitHub),  CMM2.fun
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 05:40pm 18 Nov 2020
Copy link to clipboard 
Print this post

Exactly. The idea is to require a key press and a key release before moving on to the next statement.
For a very sensitive function like KEYDOWN additional debouncing might be needed. INKEY$ isn't that sensitive however so the above combo should be good enough, for a quick test program at least.
Epsilon CMM2 projects
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 290
Posted: 07:16pm 18 Nov 2020
Copy link to clipboard 
Print this post

Thanks - I missed the debouncing logic. Very nice!
Enjoy Every Sandwich / Joe P.
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 290
Posted: 07:18pm 18 Nov 2020
Copy link to clipboard 
Print this post

Thanks - I missed the debouncing logic. Very nice!
Enjoy Every Sandwich / Joe P.
 
Print this page


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

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025