Jump to content
IGNORED

Skip sprite flag


Nop90

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
Link to comment
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.

Link to comment
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
Link to comment
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?

Link to comment
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
Link to comment
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.

 

 

Link to comment
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.

 

 

Link to comment
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.

Link to comment
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.

Link to comment
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;
}
 

karri@swing:~$ gcc test.c 
karri@swing:~$ ./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.

Link to comment
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.

Link to comment
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.

Link to comment
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
 

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...