Jump to content
Nop90

Skip sprite flag

Recommended Posts

ahah I knew you would be interested :)

so here is my code, when I want to hide a sprite from a SCB linked list, instead of rebuilding the entire list, I just do:

SCBCTL1(enemy->escb) = SCB_CTL1_SKIP_SPRITE;

Where SCB_CTL1_SKIP_SPRITE is simply the flag 0x04

 

When I want to show this sprite again, then I generally use flag 0x10 for the first SCB (zoom and palette definition) or 0x18 for the others (zoom and reuse palette)

 

So this is BLL-ish code so as far as I know with cc65, you need to set this flag in the SCB struct.

Edited by LordKraken
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

depending on what you want to set teh srpites, it might be easier to just set the hi byte of the sprite data address to zero 🙂

Share this post


Link to post
Share on other sites
1 hour ago, Nop90 said:

Could someone explain me how and for what is used the skip sprite flag?

 

A few months back, I'd had a theory that Ms. Pac-Man used that flag to handle the dots. ie, when you ate a dot, it could simply set the skip flag.

 

Turns out that wasn't the case, but I think that would be a very elegant solution for that sort of game.

Share this post


Link to post
Share on other sites

I (can) make sense to disable sprites via that flag when you have large chains of sprites (rather than setting "empty" data). Not THAT much is gained by that however.

We use it in Lacim's Legacy for that very reason.

Share this post


Link to post
Share on other sites

it's almost what I guessed. I know people that had trouble making it work.

 

I don't think it can be useful for the game I already made, but have to experiment with it

 

Share this post


Link to post
Share on other sites
18 minutes ago, sage said:

depending on what you want to set teh srpites, it might be easier to just set the hi byte of the sprite data address to zero 🙂

In nop90 case, I will have to (gently :)disagree since he wants to retain the grid data at a particular position without having to do an extra lookup later.

 

(Now I realize the context was set in a pm discussion... so the idea is to avoid drawing all the tiles when most of them are off screen. So when you move the camera and you change your grid position, you simply set this flag on or off)

Edited by LordKraken

Share this post


Link to post
Share on other sites

Also by doing that you avoid drawing at weird cordinate which I suspect is causing weird behaviour sometimes and slow down as well (but please feel free to tell me I'm just crazy :D)

Edited by LordKraken

Share this post


Link to post
Share on other sites

you mainly avoid reading the rest of the sprite SCB and data.

weird corordinates is not the problem for the hardware.

Share this post


Link to post
Share on other sites

I'm going to use this thread for other questions since are all related to the optimization of lawnmower.

 

I'm using SUZY offsets to speedup the drawing, this way I can reuse a lot o of the tiles chain, but I have problems at the borders.

 

I supposed that the offsets affects the rendered window on the phisical framebuffer, that I once read can be larger of 160x102, but someone said me it isn't so and SUZY v and h offsets are only offsets applied when drawing sprites.

 

I made a test setting 20 pixels of offsets, than in a  while(1) loop I draw a sprite in the center and half outside all the 4 borders: everything works fine, so I thought that offset works without changing the phisical size of the buffer.

 

But using the offsets in the games, where values changes at every frame, I can't draw sprites crossing two of the borders (depending the sliding direction obtained changing the SUZY offsets), just like suzy is expected to trim pixels out of the physical fb. 

 

What's happening? How do the offsets works?

 

If I have to enlarge the framebuffer (+16 pixels on every side) how can I do it?

Share this post


Link to post
Share on other sites

@Nop90 What do you mean by "offset"? HOFF/VOFF registers ($fc04/$fc06)?

 

HOFF/VOFF are only values subtracted from sprites coordinates and are used to move around virtual windows in sprites coordinate space. They don't affect framebuffer location and AFAIK there is no way to extend framebuffer dimensions.

 

Other offsets are HSIZOFF / VSIZOFF ($fc28/$fc2a) but they're some exotic values used to initialize size accummulator.

Edited by laoo

Share this post


Link to post
Share on other sites

Solved, found that if I set the position of a sprite using the value stored in an unsigned char, the implicit cast to signed int causes problems.

 

The values I use are in the range 0-160, so it should work.

 

Not the first weird behaviour of cc65 i found. Some month ago I found that sometime it doesn't respect ansi c priority of math operators.

 

 

Share this post


Link to post
Share on other sites

If you make an implicite cast of a one byte entity to a two byte entity then the second byte is taken from memory.

Share this post


Link to post
Share on other sites
4 hours ago, karri said:

If you make an implicite cast of a one byte entity to a two byte entity then the second byte is taken from memory.

Is this standard c behaviour.

 

If yes probably I worked too much with 32 bit memory aligned architectures.

 

 

Share this post


Link to post
Share on other sites
5 hours ago, Nop90 said:

Is this standard c behaviour.

 

If yes probably I worked too much with 32 bit memory aligned architectures.

 

 

Sure. I mean you can make silly casts. The compiler cannot know what kind of bits is where in memory. You may be surprised if you make some int casts on a 64 bit machine.

Share this post


Link to post
Share on other sites
5 hours ago, laoo said:

wait a minute... could you post some example of such cast?

 

 

ty = sy;
	for(j=offy-1;j<offy+7;j++) 
	{
		tx = sx;
		for(i=offx-1;i<offx+12;i++)
		{
			if((i>=0) && (j>=0) && (i<mapx) && (j<mapy))
			{
				mapij = map(i,j);
				if(mapij==42)
					ttile = tiles[1];
				else if(mapij>2 && mapij<6)
					ttile = tiles[mapij + ((framecount&4)?10:0)];
				else
					ttile = tiles[mapij];
			}
			else
				ttile =tiles[0];			
                
            addTile(
				TILES_FIELD,
				ttile,
				scrollingx ? tx - xx - 32 : tx,
				scrollingy ? ty - yy - 16: ty
				);
			tx += 16;
		}
		ty += 16;
	}

This is the (unoptimized) main loop for drawing the tiles on the screen, defining tx and tx as unsigned char gives the problems, I solved defining them signed int.

 

addTiles only sets the value of sprites position and image data pointer in a sprites array.

Share this post


Link to post
Share on other sites

If we have a pointer to an array of chars

 

char data[] = {1,2,3,4,5,6,7};

 

and then I claim it to be an int

 

int a = *(int *)&data[1];

 

What do you expect a to be?

 

#include <stdio.h>

int main()
{
    char data[] = {1,2,3,4,5,6,7};
    int a = *(int *)&data[1];
    printf("%d\n", a);
    return 1;
}
 

[email protected]:~$ gcc test.c 
[email protected]:~$ ./a.out 
84148994
 

Any language that has a pointer is bound to have problems sooner or later. In C the "int" may have any number of bits depending on the architecture.

 

I use signed chars a lot in cc65. They work well.

Share this post


Link to post
Share on other sites

@karri This is trivially true. That's why it's erroneous to perform such casts. But variables in Nop90's code are not accessed through pointers so it's not the case. Look at the sample code and initial problem assessment:

On 12/15/2019 at 6:41 PM, Nop90 said:

Solved, found that if I set the position of a sprite using the value stored in an unsigned char, the implicit cast to signed int causes problems.

If casting unsigned char to int involves fetching garbage from memory then it's obviously a bug in the compiler.

@Nop90 Could you perform similar test to my example on cc65? Maybe you've stumbled on different problem because it's hard to believe that cc65 has such grave bug in casting.

Share this post


Link to post
Share on other sites

In the next days (If i survive all this 'Xmas business lunches and parties) I'll post a simple rom + sources that shows this problem and the other one I found with operators precedence (that I solve using all the parentesis I can).

 

@laoo,what is 'your example on cc65'? give me a link please.

Share this post


Link to post
Share on other sites

well, coded a test in 5 mins.

 

Run the rom and check the code. Can you see the problem?

 

Is it the compiler or a silly mistake by me?

 

 

test.lnx testoffset.zip

Edited by Nop90

Share this post


Link to post
Share on other sites

The reason is that off is defined as unsigned char.

 

With signed char the math goes:

;
; sp_img.hpos=180-off;
;
        lda     #$B4
        jsr     pusha0
        ldy     #$02
        lda     (sp),y
        bpl     L0041
        ldx     #$FF
L0041:  jsr     tossubax
        sta     _sp_img+7
        stx     _sp_img+7+1
 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...